예제 #1
0
파일: Array.cs 프로젝트: jncronin/tysila
        static unsafe void *InternalToObject(void *typedref)
        {
            // get the type from the typed reference to see if we need to box the object
            //  or simply return the address as a reference type

            void *et  = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceTypeOffset());
            void *src = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceValueOffset());

            void *etextends = *(void **)((byte *)et + ClassOperations.GetVtblExtendsVtblPtrOffset());

            if (etextends == OtherOperations.GetStaticObjectAddress("_Zu1L") ||
                etextends == OtherOperations.GetStaticObjectAddress("_ZW6System4Enum"))
            {
                // this is a boxed value type.  Get its size
                var vt_size = TysosType.GetValueTypeSize(et);

                // build a new boxed type
                var ret = MemoryOperations.GcMalloc(*(int *)((byte *)et + ClassOperations.GetVtblTypeSizeOffset()));

                // dst ptr
                var dst = (byte *)ret + ClassOperations.GetBoxedTypeDataOffset();

                CopyMem(dst, (byte *)src, vt_size);

                return(ret);
            }
            else
            {
                // simply copy the reference
                return(*(void **)src);
            }
        }
예제 #2
0
        static void push_ehdr(void *eh, void *fp)
        {
            if (start == null)
            {
                void **new_start = (void **)MemoryOperations.GcMalloc(stack_length * sizeof(void *));

                fixed(void ***start_addr = &start)
                {
                    if (OtherOperations.CompareExchange((void **)start_addr, (void *)new_start) == null)
                    {
                        end = start + stack_length;
                        cur = start;
                        System.Diagnostics.Debugger.Log(0, "libsupcs", "new ehdr stack at " + ((ulong)start).ToString("X") + "-" + ((ulong)end).ToString("X"));
                    }
                }
            }

            if ((cur + 1) >= end)
            {
                System.Diagnostics.Debugger.Break();
                throw new OutOfMemoryException("exception header stack overflowed");
            }

            //if(System.Threading.Thread.CurrentThread.ManagedThreadId != 1)
            //    System.Diagnostics.Debugger.Log(0, "libsupcs", "exceptions: push_ehdr: " + ((ulong)eh).ToString("X"));

            // the following should be atomic for the current stack only, so disabling interrupts is
            //  sufficient
            var state = OtherOperations.EnterUninterruptibleSection();

            *cur++ = eh;
            *cur++ = fp;
            OtherOperations.ExitUninterruptibleSection(state);
        }
예제 #3
0
        internal static void leave_try(void *eh)
        {
            void *fp     = PopFramePointer();
            void *popped = PopEhdr();

            if (eh != popped)
            {
                System.Diagnostics.Debugger.Log(0, "libsupcs", "leave_try: popping incorrect exception header");
                System.Diagnostics.Debugger.Log(0, "libsupcs", "expected: " + ((ulong)eh).ToString("X"));
                System.Diagnostics.Debugger.Log(0, "libsupcs", "got: " + ((ulong)popped).ToString("X") + ", fp: " + ((ulong)fp).ToString("X"));
                System.Diagnostics.Debugger.Log(0, "libsupcs", "start: " + ((ulong)start).ToString("X"));
                System.Diagnostics.Debugger.Log(0, "libsupcs", "end: " + ((ulong)end).ToString("X"));
                System.Diagnostics.Debugger.Log(0, "libsupcs", "cur: " + ((ulong)cur).ToString("X"));
                System.Diagnostics.Debugger.Log(0, "libsupcs", "calling_pc: " + ((ulong)OtherOperations.GetUnwinder().UnwindOne().GetInstructionPointer()).ToString("X"));
                while (true)
                {
                    ;
                }
            }

            void **ehdr = (void **)eh;

            int eh_type = *(int *)ehdr;

            if (eh_type == 2)
            {
                // handle finally clause
                void *handler = *(ehdr + 1);
                OtherOperations.CallI(fp, handler);
                PopFramePointer();
                PopEhdr();
            }
        }
예제 #4
0
파일: Array.cs 프로젝트: jncronin/tysila
        static unsafe void InternalSetValue(void *typedref, void *objval)
        {
            // get the type from the typed reference to see if we need to unbox the object
            //  or store as a reference type

            void *et  = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceTypeOffset());
            void *ptr = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceValueOffset());

            void *etextends = *(void **)((byte *)et + ClassOperations.GetVtblExtendsVtblPtrOffset());

            if (etextends == OtherOperations.GetStaticObjectAddress("_Zu1L") ||
                etextends == OtherOperations.GetStaticObjectAddress("_ZW6System4Enum"))
            {
                // this is a boxed value type.  Get its size
                var vt_size = TysosType.GetValueTypeSize(et);

                // src ptr
                void *src = *(void **)((byte *)objval + ClassOperations.GetBoxedTypeDataOffset());

                CopyMem((byte *)ptr, (byte *)src, vt_size);
            }
            else
            {
                // simply copy the reference
                *(void **)ptr = objval;
            }
        }
예제 #5
0
 internal static unsafe void StackTrace_GetStackFramesInternal(void *sfh, int iSkip, bool fNeedFileInfo, Exception e)
 {
     /* We set the 'reentrant' member of the stack frame helper here to prevent InitializeSourceInfo running further and set
      * iFrameCount to zero to prevent stack traces occuring via CoreCLR */
     *(int *)((byte *)OtherOperations.GetStaticObjectAddress("_ZW20System#2EDiagnostics16StackFrameHelperS")
              + ClassOperations.GetStaticFieldOffset("_ZW20System#2EDiagnostics16StackFrameHelper", "t_reentrancy"))      = 1;
     *(int *)((byte *)sfh + ClassOperations.GetFieldOffset("_ZW20System#2EDiagnostics16StackFrameHelper", "iFrameCount")) = 0;
 }
예제 #6
0
 internal static void enter_try(void *eh, void *fp)
 {
     if (eh == PeekEhdr())
     {
         System.Diagnostics.Debugger.Log(0, "libsupcs", "enter_try: recursive try block found from calling_pc: " +
                                         ((ulong)OtherOperations.GetUnwinder().UnwindOne().GetInstructionPointer()).ToString("X"));
     }
     PushEhdr(eh, fp);
 }
예제 #7
0
파일: Metadata.cs 프로젝트: jncronin/tysila
        private static void load_mscorlib()
        {
            var str = AssemblyLoader.LoadAssembly("mscorlib");

            metadata.PEFile pef = new metadata.PEFile();
            var             m   = pef.Parse(str, AssemblyLoader);

            AssemblyLoader.AddToCache(m, "mscorlib");
            mscorlib = m;
            BinaryAssemblyLoader.ptr_cache[(ulong)OtherOperations.GetStaticObjectAddress("mscorlib")] = m;
        }
예제 #8
0
        static void *peek_ehdr()
        {
            if (start == null || (void **)cur <= (void **)start)
            {
                return(null);
            }

            var state = OtherOperations.EnterUninterruptibleSection();
            var ret   = *(cur - 2);

            OtherOperations.ExitUninterruptibleSection(state);

            return(ret);
        }
예제 #9
0
        internal static int Assert_ShowDefaultAssertDialog(string conditionString, string message, string stackTrace, string windowTitle)
        {
            OtherOperations.EnterUninterruptibleSection();

            System.Diagnostics.Debugger.Log(0, "Assert", windowTitle);
            System.Diagnostics.Debugger.Log(0, "Assert", conditionString);
            System.Diagnostics.Debugger.Log(0, "Assert", message);
            System.Diagnostics.Debugger.Log(0, "Assert", stackTrace);

            while (true)
            {
                ;
            }
        }
예제 #10
0
        static unsafe byte InternalGetCorElementType(void *enum_obj)
        {
            var enum_type = GetUnderlyingEnumTypeVtbl(**(void ***)enum_obj);

            if (enum_type == OtherOperations.GetStaticObjectAddress("_Zi"))
            {
                return((byte)metadata.CorElementType.I4);
            }
            else if (enum_type == OtherOperations.GetStaticObjectAddress("_Zx"))
            {
                return((byte)metadata.CorElementType.I8);
            }

            throw new NotImplementedException();
        }
예제 #11
0
        static void *pop_fp()
        {
            if (start == null || cur <= start)
            {
                System.Diagnostics.Debugger.Break();
                throw new OutOfMemoryException("exception header stack underflowed");
            }

            var state = OtherOperations.EnterUninterruptibleSection();
            var ret   = *--cur;

            OtherOperations.ExitUninterruptibleSection(state);

            return(ret);
        }
예제 #12
0
        static void *pop_ehdr()
        {
            if (start == null || (void **)cur <= (void **)start)
            {
                System.Diagnostics.Debugger.Break();
                throw new OutOfMemoryException("exception header stack underflowed");
            }

            var state = OtherOperations.EnterUninterruptibleSection();
            var ret   = *--cur;

            OtherOperations.ExitUninterruptibleSection(state);

            return(ret);

            //if (System.Threading.Thread.CurrentThread.ManagedThreadId != 1)
            //    System.Diagnostics.Debugger.Log(0, "libsupcs", "exceptions: pop_ehdr: " + ((ulong)*cur).ToString("X"));
        }
예제 #13
0
파일: Array.cs 프로젝트: jncronin/tysila
        /* Build an array of a particular type */
        public static unsafe T[] CreateSZArray <T>(int nitems, void *data_addr)
        {
            TysosType arrtt  = (TysosType)typeof(T[]);
            TysosType elemtt = (TysosType)typeof(T);

            int elemsize;

            if (elemtt.IsValueType)
            {
                elemsize = elemtt.GetClassSize() - ClassOperations.GetBoxedTypeDataOffset();
            }
            else
            {
                elemsize = OtherOperations.GetPointerSize();
            }

            if (data_addr == null)
            {
                data_addr = MemoryOperations.GcMalloc(elemsize * nitems);
            }

            byte *ret = (byte *)MemoryOperations.GcMalloc(ArrayOperations.GetArrayClassSize() + 8);     // extra space for lobounds and length array

            void *vtbl = *(void **)((byte *)CastOperations.ReinterpretAsPointer(arrtt) + ClassOperations.GetSystemTypeImplOffset());

            *(void **)(ret + ClassOperations.GetVtblFieldOffset()) = vtbl;
            *(ulong *)(ret + ClassOperations.GetMutexLockOffset()) = 0;

            *(void **)(ret + ArrayOperations.GetElemTypeOffset())   = *(void **)((byte *)CastOperations.ReinterpretAsPointer(elemtt) + ClassOperations.GetSystemTypeImplOffset());
            *(int *)(ret + ArrayOperations.GetElemSizeOffset())     = elemsize;
            *(void **)(ret + ArrayOperations.GetInnerArrayOffset()) = data_addr;
            *(void **)(ret + ArrayOperations.GetLoboundsOffset())   = ret + ArrayOperations.GetArrayClassSize();
            *(void **)(ret + ArrayOperations.GetSizesOffset())      = ret + ArrayOperations.GetArrayClassSize() + 4;
            *(int *)(ret + ArrayOperations.GetRankOffset())         = 1;
            *(int *)(ret + ArrayOperations.GetArrayClassSize())     = 0;      // lobounds[0]
            *(int *)(ret + ArrayOperations.GetArrayClassSize() + 4) = nitems; // sizes[0]

            return((T[])CastOperations.ReinterpretAsObject(ret));
        }
예제 #14
0
파일: Metadata.cs 프로젝트: jncronin/tysila
            public override DataInterface LoadAssembly(string name)
            {
                void *ptr;

                System.Diagnostics.Debugger.Log(0, "metadata", "Metadata.BinaryAssemblyLoader.LoadAssembly: request to load " + name);
                if (name == "mscorlib" || name == "mscorlib.dll")
                {
                    ptr = OtherOperations.GetStaticObjectAddress("mscorlib");
                }
                else if (name == "libsupcs" || name == "libsupcs.dll")
                {
                    ptr = OtherOperations.GetStaticObjectAddress("libsupcs");
                }
                else if (name == "metadata" || name == "metadata.dll")
                {
                    ptr = OtherOperations.GetStaticObjectAddress("metadata");
                }
                else
                {
                    ptr = JitOperations.GetAddressOfObject(name);
                }

                return(new BinaryInterface(ptr));
            }
예제 #15
0
        static void GetExecutingAssembly(StackCrawlMarkHandle scmh, TysosModule.ObjectHandleOnStack ret)
        {
            int scm = *(int *)scmh.ptr;

            System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosAssembly.GetExecutingAssembly: scm: " + scm.ToString());

            Unwinder u = OtherOperations.GetUnwinder();

            u.UnwindOne();
            u.UnwindOne();      // we are double-nested within coreclr so unwind this and calling method (GetExecutingAssembly(ref StackMarkHandle)) first

            switch (scm)
            {
            case 0:
                break;

            case 1:
                u.UnwindOne();
                break;

            case 2:
                u.UnwindOne();
                u.UnwindOne();
                break;

            default:
                System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosAssembly.GetExecutingAssembly: unsupported scm: " + scm.ToString());
                throw new NotSupportedException();
            }

            System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosAssembly.GetExecutingAssembly: requested pc " + ((ulong)u.GetInstructionPointer()).ToString("X"));

            void *offset;
            var   name = JitOperations.GetNameOfAddress((void *)u.GetInstructionPointer(), out offset);

            if (name == null)
            {
                System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosAssembly.GetExecutingAssembly: symbol not found");
                *ret.ptr = null;
                return;
            }

            System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosAssembly.GetExecutingAssembly: found method " + name);

            var ts = Metadata.MSCorlib.DemangleObject(name);

            if (ts == null)
            {
                System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosAssembly.GetExecutingAssembly: demangler returned null");
                *ret.ptr = null;
                return;
            }
            var m = ts.Metadata;

            if (m == null)
            {
                System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosAssembly.GetExecutingAssembly: returned ts had no assembly");
                *ret.ptr = null;
                return;
            }
            var aptr = (m.file as Metadata.BinaryInterface).b;
            var retm = TysosModule.GetModule(aptr, m.AssemblyName);

            System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosAssembly.GetExecutingAssembly: returning " + retm.ass.assemblyName);
            *ret.ptr = CastOperations.ReinterpretAsPointer(retm.ass);
        }
예제 #16
0
        public override object Invoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
        {
            uint flags = 0;

            if (MethodAddress == null)
            {
                var mangled_name = mspec.MangleMethod();
                System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosMethod.Invoke: requesting run-time address for " + mangled_name);
                MethodAddress = JitOperations.GetAddressOfObject(mspec.MangleMethod());
                if (MethodAddress == null)
                {
                    System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosMethod.Invoke: jit compiling method");
                    MethodAddress = JitOperations.JitCompile(this.mspec);
                }
            }
            if (MethodAddress == null)
            {
                throw new System.Reflection.TargetException("Method does not have a defined implementation (" + OwningType.FullName + "." + Name + "())");
            }
            if (!IsStatic && (obj == null))
            {
                throw new System.Reflection.TargetException("Instance method and obj is null (" + OwningType.FullName + "." + Name + "())");
            }

            // TODO: check number and type of parameters is what the method expects

            // Get total number of parameters
            int p_length = 0;

            if (parameters != null)
            {
                p_length = parameters.Length;
            }
            if (!IsStatic)
            {
                p_length++;
            }

            // See InternalStrCpy for the rationale here
            int     max_stack_alloc = p_length > 512 ? 512 : p_length;
            IntPtr *pstack          = stackalloc IntPtr[max_stack_alloc];
            IntPtr *tstack          = stackalloc IntPtr[max_stack_alloc];

            void **ps, ts;

            if (max_stack_alloc <= 512)
            {
                ps = (void **)pstack;
                ts = (void **)tstack;
            }
            else
            {
                ps = (void **)MemoryOperations.GcMalloc(p_length * sizeof(void *));
                ts = (void **)MemoryOperations.GcMalloc(p_length * sizeof(void *));
            }

            // Build a new params array to include obj if necessary, and a tysos type array
            int curptr = 0;

            if (!IsStatic)
            {
                ps[0] = CastOperations.ReinterpretAsPointer(obj);
                ts[0] = OtherOperations.GetStaticObjectAddress("_Zu1O");
                curptr++;
            }
            if (parameters != null)
            {
                for (int i = 0; i < parameters.Length; i++, curptr++)
                {
                    var cp = CastOperations.ReinterpretAsPointer(parameters[i]);
                    ps[curptr] = cp;
                    ts[curptr] = *(void **)cp;
                }
            }

            if (!IsStatic)
            {
                flags |= invoke_flag_instance;
            }
            if (OwningType.IsValueType)
            {
                flags |= invoke_flag_vt;
            }
            if (ReturnType != null && ReturnType.IsValueType)
            {
                flags |= invoke_flag_vt_ret;
            }

            return(CastOperations.ReinterpretAsObject(InternalInvoke(MethodAddress, p_length, ps, ts,
                                                                     (ReturnType != null) ? TysosType.ReinterpretAsType(ReturnType)._impl : null, flags)));
        }
예제 #17
0
파일: Array.cs 프로젝트: jncronin/tysila
        static unsafe void *GetValueImpl(void *arr, int pos)
        {
            /* Get the element type of the array */
            void *et = *(void **)((byte *)arr + ArrayOperations.GetElemTypeOffset());

            /* Get a pointer to the source data */
            var   elem_size = *(int *)((byte *)arr + ArrayOperations.GetElemSizeOffset());
            void *ia        = *(void **)((byte *)arr + ArrayOperations.GetInnerArrayOffset());
            void *sptr      = (void *)((byte *)ia + pos * elem_size);

            /* Is this a value type? In which case we need to return a boxed value */
            void *extends = *(void **)((byte *)et + ClassOperations.GetVtblExtendsVtblPtrOffset());

            if (extends == OtherOperations.GetStaticObjectAddress("_Zu1L") ||
                extends == OtherOperations.GetStaticObjectAddress("_ZW6System4Enum"))
            {
                /* This is a value type.  We need to read the size of the element,
                 * create a new object of the appropriate size and copy the data
                 * into it */
                byte *ret = (byte *)MemoryOperations.GcMalloc(elem_size + ClassOperations.GetBoxedTypeDataOffset());
                *(void **)(ret + ClassOperations.GetVtblFieldOffset()) = et;
                *(ulong *)(ret + ClassOperations.GetMutexLockOffset()) = 0;

                /* Avoid calls to memcpy if possible */
                switch (elem_size)
                {
                case 1:
                    *(byte *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(byte *)sptr;
                    return(ret);

                case 2:
                    *(ushort *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(ushort *)sptr;
                    return(ret);

                case 4:
                    *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(uint *)sptr;
                    return(ret);

                case 8:
                    if (OtherOperations.GetPointerSize() >= 8)
                    {
                        *(ulong *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(ulong *)sptr;
                        return(ret);
                    }
                    else
                    {
                        *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset())     = *(uint *)sptr;
                        *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset() + 4) = *(uint *)((byte *)sptr + 4);
                        return(ret);
                    }

                case 16:
                    if (OtherOperations.GetPointerSize() >= 8)
                    {
                        *(ulong *)(ret + ClassOperations.GetBoxedTypeDataOffset())     = *(ulong *)sptr;
                        *(ulong *)(ret + ClassOperations.GetBoxedTypeDataOffset() + 8) = *(ulong *)((byte *)sptr + 8);
                        return(ret);
                    }
                    else
                    {
                        *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset())      = *(uint *)sptr;
                        *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset() + 4)  = *(uint *)((byte *)sptr + 4);
                        *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset() + 8)  = *(uint *)((byte *)sptr + 8);
                        *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset() + 12) = *(uint *)((byte *)sptr + 12);
                        return(ret);
                    }
                }

                /* Do data copy via memcpy */
                MemoryOperations.MemCpy(ret + ClassOperations.GetBoxedTypeDataOffset(),
                                        sptr, elem_size);
                return(ret);
            }
            else
            {
                /* Its a reference type, so just return the pointer */
                return(*(void **)sptr);
            }
        }