Beispiel #1
0
        static unsafe object to_object(TysosType enum_type, object value)
        {
            /* Convert value (of an integral type) to an enum of type 'enum_type'
             * and return its boxed value
             */

            if (enum_type == null)
            {
                throw new ArgumentNullException("enumType");
            }
            if (value == null)
            {
                throw new ArgumentException("value");
            }

            /* The incoming value type 'value' is already boxed.
             *
             * We can therefore just copy its data to a new enum object
             */

            void *value_obj   = CastOperations.ReinterpretAsPointer(value);
            void *value_vtbl  = *(void **)value_obj;
            int   value_csize = *(int *)((byte *)value_vtbl + ClassOperations.GetVtblTypeSizeOffset());

            void *ret_obj = MemoryOperations.GcMalloc(value_csize);

            MemoryOperations.MemCpy(ret_obj, value_obj, value_csize);

            void *ret_vtbl = *(void **)((byte *)CastOperations.ReinterpretAsPointer(enum_type) + ClassOperations.GetSystemTypeImplOffset());

            *(void **)ret_obj = ret_vtbl;
            *(void **)((byte *)ret_obj + ClassOperations.GetMutexLockOffset()) = null;

            return(CastOperations.ReinterpretAsObject(ret_obj));
        }
Beispiel #2
0
        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;
            }
        }
Beispiel #3
0
        static unsafe bool Equals(void *a, void *b)
        {
            /* a is guaranteed to be a System.Enum, therefore just ensuring b
             * is the same type ensures b is an enum */
            void *avtbl = *(void **)a;
            void *bvtbl = *(void **)b;

            if (avtbl != bvtbl)
            {
                return(false);
            }

            /* Get size of data to compare */
            var  tsize = *(int *)((byte *)avtbl + ClassOperations.GetVtblTypeSizeOffset()) - ClassOperations.GetBoxedTypeDataOffset();
            int *adata = (int *)((byte *)a + ClassOperations.GetBoxedTypeDataOffset());
            int *bdata = (int *)((byte *)b + ClassOperations.GetBoxedTypeDataOffset());

            /* Use lowest common denominator of int32s for comparison (most enums are int32s) */
            for (int i = 0; i < tsize; i += 4, adata++, bdata++)
            {
                if (*adata != *bdata)
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        static unsafe void Monitor_exit(byte *obj)
        {
            var tid = System.Threading.Thread.CurrentThread.ManagedThreadId;
            var mla = obj + ClassOperations.GetMutexLockOffset();

            release(mla, tid);
        }
Beispiel #6
0
        static unsafe void AssemblyName_nInit(byte *obj, out TysosAssembly assembly, bool forIntrospection, bool raiseResolveEvent)
        {
            string name = CastOperations.ReinterpretAsString(*(void **)(obj + ClassOperations.GetFieldOffset("_ZW19System#2EReflection12AssemblyName", "_Name")));

            System.Diagnostics.Debugger.Log(0, "libsupcs", "AssemblyName_nInit(" + name + ", out TysosAssembly, bool, bool) called");

            // split assembly name off from other fields
            int    comma = name.IndexOf(',');
            string Name;

            if (comma != -1)
            {
                Name = name.Substring(0, comma);
            }
            else
            {
                Name = name;
            }

            if (Name.Equals("System.Private.CoreLib"))
            {
                Name = "mscorlib";
            }

            *(void **)(obj + ClassOperations.GetFieldOffset("_ZW19System#2EReflection12AssemblyName", "_Name")) =
                CastOperations.ReinterpretAsPointer(Name);

            System.Diagnostics.Debugger.Log(0, "libsupcs", "AssemblyName_nInit - setting _Name to " + Name);

            assembly = null;
        }
Beispiel #7
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;
 }
Beispiel #8
0
        static unsafe void ReliableEnter(byte *obj, ref bool success)
        {
            var tid = System.Threading.Thread.CurrentThread.ManagedThreadId;
            var mla = obj + ClassOperations.GetMutexLockOffset();

            while (try_acquire(mla, tid) != 1)
            {
                ;
            }

            success = true;
        }
Beispiel #9
0
        static unsafe void *get_value(void *obj)
        {
            /* we can copy the entire enum object to an instance
             * of the underlying type and just change the
             * vtbl
             */

            byte *enum_vtbl = *(byte **)obj;
            int   enum_size = *(int *)(enum_vtbl + ClassOperations.GetVtblTypeSizeOffset());

            void **enum_ti = *(void ***)enum_vtbl;
            void * ut_vtbl = *(enum_ti + 1);

            void *new_obj = MemoryOperations.GcMalloc(enum_size);

            MemoryOperations.MemCpy(new_obj, obj, enum_size);

            *(void **)new_obj = ut_vtbl;
            *(void **)((byte *)new_obj + ClassOperations.GetMutexLockOffset()) = null;

            return(new_obj);
        }
Beispiel #10
0
        /* 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));
        }
Beispiel #11
0
        static unsafe void InternalGetReference(void *arr, System.TypedReference *typedref, int ranks, int *rank_indices)
        {
            // idx = rightmost-index + 2nd-right * rightmost-size + 3rd-right * 2nd-right-size * right-size + ...

            // rank checking is done by System.Array members in coreclr
            int *lovals = *(int **)((byte *)arr + ArrayOperations.GetLoboundsOffset());
            int *sizes  = *(int **)((byte *)arr + ArrayOperations.GetSizesOffset());

            // first get index of first rank
            if (rank_indices[0] > sizes[0])
            {
                throw new IndexOutOfRangeException();
            }
            int index = rank_indices[0] - lovals[0];

            // now repeat mul rank size; add rank index; rank-1 times
            for (int rank = 1; rank < ranks; rank++)
            {
                if (rank_indices[rank] > sizes[rank])
                {
                    throw new IndexOutOfRangeException();
                }

                index *= sizes[rank];
                index += rank_indices[rank];
            }

            // get pointer to actual data
            int   et_size = *(int *)((byte *)arr + ArrayOperations.GetElemSizeOffset());
            void *ptr     = *(byte **)((byte *)arr + ArrayOperations.GetInnerArrayOffset()) + index * et_size;

            // store to the typed reference
            *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceValueOffset()) = ptr;
            *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceTypeOffset())  =
                *(void **)((byte *)arr + ArrayOperations.GetElemTypeOffset());
        }
Beispiel #12
0
        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);
            }
        }