From 4b4aad7217d3292650e77eec2cf4c198ea9c3b4b Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Wed, 23 Nov 2016 19:09:09 +0900 Subject: Imported Upstream version 1.1.0 --- src/vm/invokeutil.h | 335 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 src/vm/invokeutil.h (limited to 'src/vm/invokeutil.h') diff --git a/src/vm/invokeutil.h b/src/vm/invokeutil.h new file mode 100644 index 0000000000..b991674cec --- /dev/null +++ b/src/vm/invokeutil.h @@ -0,0 +1,335 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// + +// +//////////////////////////////////////////////////////////////////////////////// +// This module defines a Utility Class used by reflection +// +// + +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef __INVOKEUTIL_H__ +#define __INVOKEUTIL_H__ + +// The following class represents the value class +#include + +struct InterfaceMapData +{ + REFLECTCLASSBASEREF m_targetType; + REFLECTCLASSBASEREF m_interfaceType; + PTRARRAYREF m_targetMethods; + PTRARRAYREF m_interfaceMethods; +}; + +// Calling Conventions +// NOTE: These are defined in CallingConventions.cs They must match up. +#define Standard_CC 0x0001 +#define VarArgs_CC 0x0002 +#define Any_CC (Standard_CC | VarArgs_CC) + +#define PRIMITIVE_TABLE_SIZE ELEMENT_TYPE_STRING +#define PT_Primitive 0x01000000 + +// Define the copy back constants. +#define COPYBACK_PRIMITIVE 1 +#define COPYBACK_OBJECTREF 2 +#define COPYBACK_VALUECLASS 3 + +#include + +class ReflectMethodList; +class ArgDestination; + +// Structure used to track security access checks efficiently when applied +// across a range of methods, fields etc. +// +class RefSecContext : public AccessCheckContext +{ +public: + RefSecContext(AccessCheckOptions::AccessCheckType accessCheckType) + : m_fCheckedCaller(false), + m_fCheckedPerm(false), + m_fCallerHasPerm(false), +#ifdef FEATURE_REMOTING + m_fSkippingRemoting(false), +#endif + m_pCaller(NULL), + m_pCallerDomain(NULL), + m_accessCheckType(accessCheckType) + { + LIMITED_METHOD_CONTRACT; + } + + virtual MethodTable* GetCallerMT(); + virtual MethodDesc* GetCallerMethod(); + virtual Assembly* GetCallerAssembly(); + virtual bool IsCalledFromInterop(); + + // The caller will be computed lazily by the reflection system. + virtual bool IsCallerCritical() + { + LIMITED_METHOD_CONTRACT; + + return false; + } + + AccessCheckOptions::AccessCheckType GetAccessCheckType() const + { + LIMITED_METHOD_CONTRACT; + return m_accessCheckType; + } + + AppDomain* GetCallerDomain(); + +private: + bool m_fCheckedCaller; + bool m_fCheckedPerm; + bool m_fCallerHasPerm; + +#ifdef FEATURE_REMOTING + bool m_fSkippingRemoting; +#endif + + // @review GENERICS: + // These method descriptors may be shared between compatible instantiations + // Check that this does not open any security holes + MethodDesc* m_pCaller; + AppDomain* m_pCallerDomain; + + AccessCheckOptions::AccessCheckType m_accessCheckType; + + void FindCaller(); +}; + +// This class abstracts the functionality which creats the +// parameters on the call stack and deals with the return type +// inside reflection. +// +class InvokeUtil +{ + +public: + static void CopyArg(TypeHandle th, OBJECTREF *obj, ArgDestination *argDest); + + // Given a type, this routine will convert an return value representing that + // type into an ObjectReference. If the type is a primitive, the + // value is wrapped in one of the Value classes. + static OBJECTREF CreateObject(TypeHandle th, void * pValue); + + // This is a special purpose Exception creation function. It + // creates the TargetInvocationExeption placing the passed + // exception into it. + static OBJECTREF CreateTargetExcept(OBJECTREF* except); + + // This is a special purpose Exception creation function. It + // creates the ReflectionClassLoadException placing the passed + // classes array and exception array into it. + static OBJECTREF CreateClassLoadExcept(OBJECTREF* classes,OBJECTREF* except); + + // Validate that the field can be widened for Set + static void ValidField(TypeHandle th, OBJECTREF* value); + + // ChangeType + // This method will invoke the Binder change type method on the object + // binder -- The Binder object + // srcObj -- The source object to be changed + // th -- The TypeHandel of the target type + // locale -- The locale passed to the class. + static OBJECTREF ChangeType(OBJECTREF binder,OBJECTREF srcObj,TypeHandle th,OBJECTREF locale); + + // CreatePrimitiveValue + // This routine will validate the object and then place the value into + // the destination + // dstType -- The type of the destination + // srcType -- The type of the source + // srcObj -- The Object containing the primitive value. + // pDst -- poiner to the destination + static void CreatePrimitiveValue(CorElementType dstType, CorElementType srcType, OBJECTREF srcObj, ARG_SLOT* pDst); + + // CreatePrimitiveValue + // This routine will validate the object and then place the value into + // the destination + // dstType -- The type of the destination + // srcType -- The type of the source + // pSrc -- pointer to source data. + // pSrcMT - MethodTable of source type + // pDst -- poiner to the destination + static void CreatePrimitiveValue(CorElementType dstType,CorElementType srcType, + void *pSrc, MethodTable *pSrcMT, ARG_SLOT* pDst); + + // IsPrimitiveType + // This method will verify the passed in type is a primitive or not + // type -- the CorElementType to check for + inline static DWORD IsPrimitiveType(const CorElementType type) + { + LIMITED_METHOD_CONTRACT; + + if (type >= PRIMITIVE_TABLE_SIZE) + { + if (ELEMENT_TYPE_I==type || ELEMENT_TYPE_U==type) + { + return TRUE; + } + return 0; + } + + return (PT_Primitive & PrimitiveAttributes[type]); + } + + static BOOL IsVoidPtr(TypeHandle th); + + // CanPrimitiveWiden + // This method determines if the srcType and be widdened without loss to the destType + // destType -- The target type + // srcType -- The source type. + inline static DWORD CanPrimitiveWiden(const CorElementType destType, const CorElementType srcType) + { + LIMITED_METHOD_CONTRACT; + + if (destType >= PRIMITIVE_TABLE_SIZE || srcType >= PRIMITIVE_TABLE_SIZE) + { + if ((ELEMENT_TYPE_I==destType && ELEMENT_TYPE_I==srcType) || + (ELEMENT_TYPE_U==destType && ELEMENT_TYPE_U==srcType)) + { + return TRUE; + } + return 0; + } + return ((1 << destType) & PrimitiveAttributes[srcType]); + } + + // Field Stuff. The following stuff deals with fields making it possible + // to set/get field values on objects + + // SetValidField + // Given an target object, a value object and a field this method will set the field + // on the target object. The field must be validate before calling this. + static void SetValidField(CorElementType fldType, TypeHandle fldTH, FieldDesc* pField, OBJECTREF* target, OBJECTREF* value, TypeHandle declaringType, CLR_BOOL *pDomainInitialized); + + static OBJECTREF GetFieldValue(FieldDesc* pField, TypeHandle fieldType, OBJECTREF* target, TypeHandle declaringType, CLR_BOOL *pDomainInitialized); + + // ValidateObjectTarget + // This method will validate the Object/Target relationship + // is correct. It throws an exception if this is not the case. + static void ValidateObjectTarget(FieldDesc* pField,TypeHandle fldType,OBJECTREF *target); + + // Create reflection pointer wrapper + static OBJECTREF CreatePointer(TypeHandle th, void * p); + + static TypeHandle GetPointerType(OBJECTREF pObj); + static void* GetPointerValue(OBJECTREF pObj); + static void* GetIntPtrValue(OBJECTREF pObj); + + // Check accessability of a type or nested type. + static void CanAccessClass(RefSecContext* pCtx, + MethodTable* pClass, + BOOL checkAccessForImplicitValueTypeCtor = FALSE); + + static void CanAccessMethod(MethodDesc* pMeth, + MethodTable* pParentMT, + MethodTable* pInstanceMT, + RefSecContext* pSCtx, + BOOL fCriticalToFullDemand = TRUE, + BOOL checkSkipVer = FALSE); + + // Check accessability of a field + static void CanAccessField(RefSecContext* pCtx, + MethodTable* pTargetMT, + MethodTable* pInstanceMT, + FieldDesc* pTargetField); + + // If a method has a linktime demand attached, perform it. + static void CheckLinktimeDemand(RefSecContext *pCtx, MethodDesc *pMeth); + + // + // Check to see if the target of a reflection operation is on a remote object + // + // Arguments: + // pDesc - item being accessed (MethodDesc, FieldDesc, etc) + // pTargetMT - object being reflected on + + template + static bool IsTargetRemoted(T *pDesc, MethodTable *pTargetMT) + { + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + PRECONDITION(CheckPointer(pDesc)); + } + CONTRACTL_END; + + if (pDesc->IsStatic()) + return FALSE; + + if (pTargetMT == NULL) + return FALSE; + +#ifdef FEATURE_REMOTING + if (pTargetMT->IsTransparentProxy()) + return TRUE; +#endif + return FALSE; + } + + static BOOL IsCriticalWithConversionToFullDemand(MethodTable* pMT); + static BOOL IsCriticalWithConversionToFullDemand(MethodDesc* pMD, MethodTable* pInstanceMT); + static BOOL IsCriticalWithConversionToFullDemand(FieldDesc* pFD, MethodTable* pInstanceMT); + + static AccessCheckOptions::AccessCheckType GetInvocationAccessCheckType(BOOL targetRemoted = FALSE); + + static bool IsDangerousMethod(MethodDesc *pMD); + +private: + // Check accessability of a type or nested type. + static void CheckAccessClass(RefSecContext *pCtx, + MethodTable *pClass, + BOOL checkAccessForImplicitValueTypeCtor = FALSE); + +public: + // Check accessability of a method + static void CheckAccessMethod(RefSecContext *pCtx, + MethodTable *pTargetMT, + MethodTable *pInstanceMT, + MethodDesc *pTargetMethod); + +private: + // Check accessability of a field + static void CheckAccessField(RefSecContext *pCtx, + MethodTable *pTargetMT, + MethodTable *pInstanceMT, + FieldDesc *pTargetField); + + // Check accessability of a field or method. + // pTargetMD should be NULL for a field, and may be NULL for a method. + // If checking a generic method with a method instantiation, + // the method should be in as pOptionalTargetMethod so + // that the accessibilty of its type arguments is checked too. + static void CheckAccess(RefSecContext *pCtx, + MethodTable *pTargetMT, + MethodTable *pInstanceMT, + MethodDesc *pTargetMD, + FieldDesc *pTargetField, + const AccessCheckOptions &accessCheckOptions); + + static void* CreateByRef(TypeHandle dstTh,CorElementType srcType, TypeHandle srcTH,OBJECTREF srcObj, OBJECTREF *pIncomingObj); + + // GetBoxedObject + // Given an address of a primitve type, this will box that data... + static OBJECTREF GetBoxedObject(TypeHandle th,void* pData); + +private: + // The Attributes Table + // This constructs a table of legal widening operations + // for the primitive types. + static DWORD const PrimitiveAttributes[PRIMITIVE_TABLE_SIZE]; +}; + + +#endif // __INVOKEUTIL_H__ -- cgit v1.2.3