📄 jclmetadata.pas
字号:
constructor Create(const ATable: TJclClrTable); override;
function Add(const ARow: TJclClrTablePropertyDefRow): Integer;
public
destructor Destroy; override;
property ParentIdx: DWORD read FParentIdx;
property PropertyListIdx: DWORD read FPropertyListIdx;
property Parent: TJclClrTableTypeDefRow read GetParent;
property Properties[const Idx: Integer]: TJclClrTablePropertyDefRow read GetProperty;
property PropertyCount: Integer read GetPropertyCount;
end;
TJclClrTablePropertyMap = class(TJclClrTable)
private
function GetRow(const Idx: Integer): TJclClrTablePropertyMapRow;
protected
class function TableRowClass: TJclClrTableRowClass; override;
procedure Update; override;
public
property Rows[const Idx: Integer]: TJclClrTablePropertyMapRow read GetRow; default;
end;
TJclClrTableStandAloneSigRow = class(TJclClrTableRow)
private
FSignatureOffset: DWORD;
function GetSignature: TJclClrBlobRecord;
protected
constructor Create(const ATable: TJclClrTable); override;
public
property SignatureOffset: DWORD read FSignatureOffset;
property Signature: TJclClrBlobRecord read GetSignature;
end;
TJclClrTableStandAloneSig = class(TJclClrTable)
private
function GetRow(const Idx: Integer): TJclClrTableStandAloneSigRow;
protected
class function TableRowClass: TJclClrTableRowClass; override;
public
property Rows[const Idx: Integer]: TJclClrTableStandAloneSigRow read GetRow; default;
end;
TJclClrTypeVisibility =
(tvNotPublic, tvPublic, tvNestedPublic,
tvNestedPrivate, tvNestedFamily, tvNestedAssembly,
tvNestedFamANDAssem, tvNestedFamORAssem);
TJclClrClassLayout = (clAuto, clSequential, clExplicit);
TJclClrClassSemantics = (csClass, csInterface);
TJclClrStringFormatting = (sfAnsi, sfUnicode, sfAutoChar);
TJclClrTypeAttribute =
(taAbstract, taSealed, taSpecialName, taImport,
taSerializable, taBeforeFieldInit, taRTSpecialName, taHasSecurity);
TJclClrTypeAttributes = set of TJclClrTypeAttribute;
TJclClrTableTypeDefRow = class(TJclClrTableRow)
private
FNamespaceOffset: DWORD;
FNameOffset: DWORD;
FFlags: DWORD;
FExtendsIdx: DWORD;
FFieldListIdx: DWORD;
FMethodListIdx: DWORD;
FFields: TList;
FMethods: TList;
function GetName: WideString;
function GetNamespace: WideString;
function GetField(const Idx: Integer): TJclClrTableFieldDefRow;
function GetFieldCount: Integer;
function GetMethod(const Idx: Integer): TJclClrTableMethodDefRow;
function GetMethodCount: Integer;
procedure UpdateFields;
procedure UpdateMethods;
function GetFullName: WideString;
function GetAttributes: TJclClrTypeAttributes;
function GetClassLayout: TJclClrClassLayout;
function GetClassSemantics: TJclClrClassSemantics;
function GetStringFormatting: TJclClrStringFormatting;
function GetVisibility: TJclClrTypeVisibility;
function GetExtends: TJclClrTableRow;
protected
constructor Create(const ATable: TJclClrTable); override;
procedure Update; override;
public
destructor Destroy; override;
function DumpIL: string; override;
function HasField: Boolean;
function HasMethod: Boolean;
property Flags: DWORD read FFlags;
property NameOffset: DWORD read FNameOffset;
property NamespaceOffset: DWORD read FNamespaceOffset;
property ExtendsIdx: DWORD read FExtendsIdx;
property FieldListIdx: DWORD read FFieldListIdx;
property MethodListIdx: DWORD read FMethodListIdx;
property Name: WideString read GetName;
property Namespace: WideString read GetNamespace;
property FullName: WideString read GetFullName;
property Extends: TJclClrTableRow read GetExtends;
property Attributes: TJclClrTypeAttributes read GetAttributes;
property Visibility: TJclClrTypeVisibility read GetVisibility;
property ClassLayout: TJclClrClassLayout read GetClassLayout;
property ClassSemantics: TJclClrClassSemantics read GetClassSemantics;
property StringFormatting: TJclClrStringFormatting read GetStringFormatting;
property Fields[const Idx: Integer]: TJclClrTableFieldDefRow read GetField;
property FieldCount: Integer read GetFieldCount;
property Methods[const Idx: Integer]: TJclClrTableMethodDefRow read GetMethod;
property MethodCount: Integer read GetMethodCount;
end;
TJclClrTableTypeDef = class(TJclClrTable, ITableCanDumpIL)
private
function GetRow(const Idx: Integer): TJclClrTableTypeDefRow;
protected
class function TableRowClass: TJclClrTableRowClass; override;
public
property Rows[const Idx: Integer]: TJclClrTableTypeDefRow read GetRow; default;
end;
TJclClrTableTypeRefRow = class(TJclClrTableRow)
private
FResolutionScopeIdx: DWORD;
FNamespaceOffset: DWORD;
FNameOffset: DWORD;
function GetName: WideString;
function GetNamespace: WideString;
function GetResolutionScope: TJclClrTableRow;
function GetResolutionScopeName: string;
function GetFullName: WideString;
protected
constructor Create(const ATable: TJclClrTable); override;
public
function DumpIL: string; override;
property ResolutionScopeIdx: DWORD read FResolutionScopeIdx;
property NameOffset: DWORD read FNameOffset;
property NamespaceOffset: DWORD read FNamespaceOffset;
property ResolutionScope: TJclClrTableRow read GetResolutionScope;
property ResolutionScopeName: string read GetResolutionScopeName;
property Name: WideString read GetName;
property Namespace: WideString read GetNamespace;
property FullName: WideString read GetFullName;
end;
TJclClrTableTypeRef = class(TJclClrTable)
private
function GetRow(const Idx: Integer): TJclClrTableTypeRefRow;
protected
class function TableRowClass: TJclClrTableRowClass; override;
public
property Rows[const Idx: Integer]: TJclClrTableTypeRefRow read GetRow; default;
end;
TJclClrTableTypeSpecRow = class(TJclClrTableRow)
private
FSignatureOffset: DWORD;
function GetSignature: TJclClrBlobRecord;
protected
constructor Create(const ATable: TJclClrTable); override;
public
property SignatureOffset: DWORD read FSignatureOffset;
property Signature: TJclClrBlobRecord read GetSignature;
end;
TJclClrTableTypeSpec = class(TJclClrTable)
private
function GetRow(const Idx: Integer): TJclClrTableTypeSpecRow;
protected
class function TableRowClass: TJclClrTableRowClass; override;
public
property Rows[const Idx: Integer]: TJclClrTableTypeSpecRow read GetRow; default;
end;
TJclClrTableENCMapRow = class(TJclClrTableRow)
private
FToken: DWORD;
FFuncCode: DWORD;
protected
constructor Create(const ATable: TJclClrTable); override;
property FuncCode: DWORD read FFuncCode;
end;
TJclClrTableENCMap = class(TJclClrTable)
private
function GetRow(const Idx: Integer): TJclClrTableENCMapRow;
protected
class function TableRowClass: TJclClrTableRowClass; override;
public
property Rows[const Idx: Integer]: TJclClrTableENCMapRow read GetRow; default;
end;
TJclClrTableENCLogRow = class(TJclClrTableENCMapRow)
private
FFuncCode: DWORD;
protected
constructor Create(const ATable: TJclClrTable); override;
property FuncCode: DWORD read FFuncCode;
end;
TJclClrTableENCLog = class(TJclClrTable)
private
function GetRow(const Idx: Integer): TJclClrTableENCLogRow;
protected
class function TableRowClass: TJclClrTableRowClass; override;
public
property Rows[const Idx: Integer]: TJclClrTableENCLogRow read GetRow; default;
end;
EJclMetadataError = class(EJclError);
implementation
uses
Math,
JclCIL, JclResources, JclStrings;
const
MAX_CLASS_NAME = 1024;
MAX_PATH_NAME = 260;
// Assembly attr bits, used by DefineAssembly.
afPublicKey = $0001; // The assembly ref holds the full (unhashed) public key.
afCompatibilityMask = $0070;
afSideBySideCompatible = $0000; // The assembly is side by side compatible.
afNonSideBySideAppDomain = $0010; // The assembly cannot execute with other versions if
// they are executing in the same application domain.
afNonSideBySideProcess = $0020; // The assembly cannot execute with other versions if
// they are executing in the same process.
afNonSideBySideMachine = $0030; // The assembly cannot execute with other versions if
// they are executing on the same machine.
afEnableJITcompileTracking = $8000; // From "DebuggableAttribute".
afDisableJITcompileOptimizer = $4000; // From "DebuggableAttribute".
ClrAssemblyFlagMapping: array [TJclClrAssemblyFlag] of DWORD =
(afPublicKey, afCompatibilityMask, afSideBySideCompatible,
afNonSideBySideAppDomain, afNonSideBySideProcess,
afNonSideBySideMachine, afEnableJITcompileTracking,
afDisableJITcompileOptimizer);
mrVisibilityMask = $0007;
mrPublic = $0001; // The Resource is exported from the Assembly.
mrPrivate = $0002; // The Resource is private to the Assembly.
ManifestResourceVisibilityMapping: array [TJclClrTableManifestResourceVisibility] of DWORD =
(mrPublic, mrPrivate);
// MethodDef attr bits, Used by DefineMethod.
// member access mask - Use this mask to retrieve accessibility information.
mdMemberAccessMask = $0007;
mdPrivateScope = $0000; // Member not referenceable.
mdPrivate = $0001; // Accessible only by the parent type.
mdFamANDAssem = $0002; // Accessible by sub-types only in this Assembly.
mdAssem = $0003; // Accessibly by anyone in the Assembly.
mdFamily = $0004; // Accessible only by type and sub-types.
mdFamORAssem = $0005; // Accessibly by sub-types anywhere, plus anyone in assembly.
mdPublic = $0006; // Accessibly by anyone who has visibility to this scope.
// end member access mask
// method contract attributes.
mdStatic = $0010; // Defined on type, else per instance.
mdFinal = $0020; // Method may not be overridden.
mdVirtual = $0040; // Method virtual.
mdHideBySig = $0080; // Method hides by name+sig, else just by name.
// vtable layout mask - Use this mask to retrieve vtable attributes.
mdVtableLayoutMask = $0100;
mdReuseSlot = $0000; // The default.
mdNewSlot = $0100; // Method always gets a new slot in the vtable.
// end vtable layout mask
// method implementation attributes.
mdCheckAccessOnOverride = $0200; // Overridability is the same as the visibility.
mdAbstract = $0400; // Method does not provide an implementation.
mdSpecialName = $0800; // Method is special. Name describes how.
// interop attributes
mdPinvokeImpl = $2000; // Implementation is forwarded through pinvoke.
mdUnmanagedExport = $0008; // Managed method exported via thunk to unmanaged code.
// Reserved flags for runtime use only.
mdReservedMask = $d000;
mdRTSpecialName = $1000; // Runtime should check name encoding.
mdHasSecurity = $4000; // Method has security associate with it.
mdRequireSecObject = $8000; // Method calls another method containing security code.
// MethodImpl attr bits, used by DefineMethodImpl.
// code impl mask
miCodeTypeMask = $0003; // Flags about code type.
miIL = $0000; // Method impl is IL.
miNative = $0001; // Method impl is native.
miOPTIL = $0002; // Method impl is OPTIL
miRuntime = $0003; // Method impl is provided by the runtime.
// end code impl mask
// managed mask
miManagedMask = $0004; // Flags specifying whether the code is managed or unmanaged.
miUnmanaged = $0004; // Method impl is unmanaged, otherwise managed.
miManaged = $0000; // Method impl is managed.
// end managed mask
// implementation info and interop
miForwardRef = $0010; // Indicates method is defined; used primarily in merge scenarios.
miPreserveSig = $0080; // Indicates method sig is not to be mangled to do HRESULT conversion.
miInternalCall = $1000; // Reserved for internal use.
miSynchronized = $0020; // Method is single threaded through the body.
miNoInlining = $0008; // Method may not be inlined.
miMaxMethodImplVal = $ffff; // Range check value
// Calling convention flags.
IMAGE_CEE_CS_CALLCONV_DEFAULT = $0;
IMAGE_CEE_CS_CALLCONV_VARARG = $5;
IMAGE_CEE_CS_CALLCONV_FIELD = $6;
IMAGE_CEE_CS_CALLCONV_LOCAL_SIG = $7;
IMAGE_CEE_CS_CALLCONV_PROPERTY = $8;
IMAGE_CEE_CS_CALLCONV_UNMGD = $9;
IMAGE_CEE_CS_CALLCONV_MAX = $10; // first invalid calling convention
// The high bits of the calling convention convey additional info
IMAGE_CEE_CS_CALLCONV_MASK = $0f; // Calling convention is bottom 4 bits
IMAGE_CEE_CS_CALLCONV_HASTHIS = $20; // Top bit indicates a 'this' parameter
IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS = $40; // This parameter is explicitly in the signature
// TypeDef/ExportedType attr bits, used by DefineTypeDef.
// Use this mask to retrieve the type visibility information.
tdVisibilityMask = $00000007;
tdNotPublic = $00000000; // Class is not public scope.
tdPublic = $00000001; // Class is public scope.
tdNestedPublic = $00000002; // Class is nested with public visibility.
tdNestedPrivate = $00000003; // Class is nested with private visibility.
tdNestedFamily = $00000004; // Class is nested with family visibility.
tdNestedAssembly = $00000005; // Class is nested with assembly visibility.
tdNestedFamANDAssem = $00000006; // Class is nested with family and assembly visibility.
tdNestedFamORAssem = $00000007; // Class is nested with family or assembly visibility.
// Use this mask to retrieve class layout information
tdLayoutMask = $00000018;
tdAutoLayout = $00000000; // Class fields are auto-laid out
tdSequentialLayout = $00000008; // Class fields are laid out sequentially
tdExplicitLayout = $00000010; // Layout is supplied explicit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -