src/coreclr/debug/datadescriptor-shared/README.md
This folder contains infrastructure to create data descriptors as defined in the data_descriptor.md. Data descriptors enable diagnostic tooling (debuggers, profilers, etc.) to understand the internal layout and structure of .NET runtime objects without requiring intimate knowledge of implementation details.
The generate_data_descriptors function defined in clrdatadescriptors.cmake takes the following arguments:
LIBRARY_NAME (Required) - Sets the name of the target object being createdCONTRACT_FILE (Required) - Path to the contract JSON file defining supported contractsCONTRACT_NAME (Required) - Name of the ContractDescriptor export symbolINTERFACE_TARGET (Required) - Interface target providing dependencies, include directories, and definitionsEXPORT_VISIBLE (Optional) - Controls if the CONTRACT_NAME will be exported from the DLLThe build system uses a two-phase approach:
Phase 1: Intermediary Library
datadescriptor.cpp with your datadescriptor.h and datadescriptor.inccdac-build-tool can analyzePhase 2: Contract Descriptor Generation
cdac-build-tool to process the intermediary object filesCDAC_BASELINE("identifier")
"empty" for new descriptorsCDAC_TYPES_BEGIN() / CDAC_TYPES_END()
CDAC_TYPE_* macrosCDAC_TYPE_BEGIN(typeName)
typeName must be globally unique within the descriptorCDAC_TYPE_SIZE(sizeInBytes)
sizeof(YourNativeType)CDAC_TYPE_INDETERMINATE(typeName)
CDAC_TYPE_SIZECDAC_TYPE_FIELD(typeName, fieldType, fieldName, offset)
fieldType: primitive type or another defined typefieldName: diagnostic-friendly name (use managed names for managed types)offset: byte offset, usually offsetof() or cdac_data<T>::FieldNameCDAC_TYPE_END(typeName)
typeName must match the corresponding CDAC_TYPE_BEGINCDAC_GLOBALS_BEGIN() / CDAC_GLOBALS_END()
CDAC_GLOBAL(globalName, typeName, value)
value must be a compile-time constanttypeName can be a primitive type or defined typeCDAC_GLOBAL_POINTER(globalName, address)
address must be a compile-time constant pointer or uintptr_tCDAC_GLOBAL_STRING(globalName, stringValue)
stringValue must be a compile-time string literalCDAC_GLOBAL_SUB_DESCRIPTOR(globalName, address)
address must be a compile-time constant pointer to a pointer to a contract descriptorCDAC_GLOBAL_SUB_DESCRIPTOR(GC, &(g_gc_dac_vars.gc_descriptor))For reference, see the current implementation in:
src/coreclr/vm/datadescriptor/ - Complete real-world implementation
datadescriptor.h - Headers and includesdatadescriptor.inc - Full type definitions for runtime objectscontracts.jsonc - Contract definitionsCMakeLists.txt - Build integration