diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000000..5f775353ed
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,3 @@
+---
+# We'll use defaults from the LLVM style, but with 4 columns indentation.
+BasedOnStyle: Google
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000..fb33a25390
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,80 @@
+# EditorConfig is awesome:http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Don't use tabs for indentation.
+[*]
+indent_style = space
+# (Please don't specify an indent_size here; that has too many unintended consequences.)
+
+# Code files
+[*.{cs,csx,vb,vbx}]
+indent_size = 4
+insert_final_newline = true
+charset = utf-8
+
+# Xml project files
+[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
+indent_size = 2
+
+# Xml config files
+[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
+indent_size = 2
+
+# JSON files
+[*.json]
+indent_size = 2
+
+# Dotnet code style settings:
+[*.{cs,vb}]
+# Sort using and Import directives with System.* appearing first
+dotnet_sort_system_directives_first = true
+# Avoid "this." and "Me." if not necessary
+dotnet_style_qualification_for_field = false:suggestion
+dotnet_style_qualification_for_property = false:suggestion
+dotnet_style_qualification_for_method = false:suggestion
+dotnet_style_qualification_for_event = false:suggestion
+
+# Use language keywords instead of framework type names for type references
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+
+# Suggest more modern language features when available
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+
+# CSharp code style settings:
+[*.cs]
+# Prefer "var" everywhere
+csharp_style_var_for_built_in_types = true:suggestion
+csharp_style_var_when_type_is_apparent = true:suggestion
+csharp_style_var_elsewhere = true:suggestion
+
+# Prefer method-like constructs to have a block body
+csharp_style_expression_bodied_methods = false:none
+csharp_style_expression_bodied_constructors = false:none
+csharp_style_expression_bodied_operators = false:none
+
+# Prefer property-like constructs to have an expression-body
+csharp_style_expression_bodied_properties = true:none
+csharp_style_expression_bodied_indexers = true:none
+csharp_style_expression_bodied_accessors = true:none
+
+# Suggest more modern language features when available
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+csharp_style_throw_expression = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+
+# Newline settings
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..220275c2c2
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,68 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+# Set line endings to LF, even on Windows. Otherwise, execution within Docker fails.
+# See https://help.github.com/articles/dealing-with-line-endings/
+*.sh text eol=lf
+*.bash text eol=lf
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000000..89ccfb6bf1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,38 @@
+---
+name: Bug report
+about: Create a report to help us improve
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Runtime environment (please complete the following information):**
+- Instrumentation mode: [e.g. automatic with msi installer or manual with NuGet package]
+- Tracer version: [e.g. 1.0.0]
+- OS: [e.g. Windows Server 2012 R2 ]
+- CLR: [e.g. .NET Framework 4.6.2, .NET Core 2.1]
+
+**Additional context**
+Add any other context about the problem here.
+
+
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000000..3cfd4dde3a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,22 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+
+---
+
+**Are you requesting automatic instrumentation for a framework or library? Please describe.**
+- Framework or library name : [e.g. `ASP.NET MVC`, `StackExchange.Redis`]
+- Library type: [e.g. web framework, data store, cache]
+- Library version: [e.g. 5.2]
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000000..5c93bbe2b4
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,8 @@
+Fixes #
+
+Changes proposed in this pull request:
+
+
+
+
+@DataDog/apm-dotnet
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..dd080c13a9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,271 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+# vscode
+.vscode/
+# Benchmark results
+BenchmarkDotNet.Artifacts/
+
+# VSTest results
+*.trx
+
+deploy/linux/
+deploy/AzureAppServices/
diff --git a/Datadog.Trace.Native.sln b/Datadog.Trace.Native.sln
new file mode 100644
index 0000000000..58f5c2ac28
--- /dev/null
+++ b/Datadog.Trace.Native.sln
@@ -0,0 +1,120 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.329
+MinimumVisualStudioVersion = 15.0.26124.0
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9E5F0022-0A50-40BF-AC6A-C3078585ECAB}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8CEC2042-F11C-49F5-A674-2355793B600A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Datadog.Trace.ClrProfiler.Native.Tests", "test\Datadog.Trace.ClrProfiler.Native.Tests\Datadog.Trace.ClrProfiler.Native.Tests.vcxproj", "{5728056A-51AA-4FF5-AD0C-E86E44E36102}"
+ ProjectSection(ProjectDependencies) = postProject
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF} = {6CE95C50-9533-4650-8F11-BCE30908DCDF}
+ {901F02A8-8776-4D18-80C9-05C58262C1C7} = {901F02A8-8776-4D18-80C9-05C58262C1C7}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Datadog.Trace.ClrProfiler.Native", "src\Datadog.Trace.ClrProfiler.Native\Datadog.Trace.ClrProfiler.Native.vcxproj", "{91B6272F-5780-4C94-8071-DBBA7B4F67F3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Datadog.Trace.ClrProfiler.Native.DLL", "src\Datadog.Trace.ClrProfiler.Native\Datadog.Trace.ClrProfiler.Native.DLL.vcxproj", "{C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {0686E907-996A-4D6D-A685-D9C0F932C405} = {0686E907-996A-4D6D-A685-D9C0F932C405}
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample-libs", "sample-libs", "{B9AA20A4-0F9A-47FB-B3BE-A5BDEA42EFF0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.ExampleLibrary", "sample-libs\Samples.ExampleLibrary\Samples.ExampleLibrary.csproj", "{901F02A8-8776-4D18-80C9-05C58262C1C7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.ExampleLibraryTracer", "sample-libs\Samples.ExampleLibraryTracer\Samples.ExampleLibraryTracer.csproj", "{6CE95C50-9533-4650-8F11-BCE30908DCDF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.ClrProfiler.Managed.Loader", "src\Datadog.Trace.ClrProfiler.Managed.Loader\Datadog.Trace.ClrProfiler.Managed.Loader.csproj", "{0686E907-996A-4D6D-A685-D9C0F932C405}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Debug|x64.ActiveCfg = Debug|x64
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Debug|x64.Build.0 = Debug|x64
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Debug|x86.ActiveCfg = Debug|Win32
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Release|Any CPU.ActiveCfg = Release|Win32
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Release|x64.ActiveCfg = Release|x64
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Release|x64.Build.0 = Release|x64
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Release|x86.ActiveCfg = Release|Win32
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Release|x86.Build.0 = Release|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Debug|x64.ActiveCfg = Debug|x64
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Debug|x64.Build.0 = Debug|x64
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Debug|x86.ActiveCfg = Debug|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Debug|x86.Build.0 = Debug|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Release|Any CPU.ActiveCfg = Release|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Release|x64.ActiveCfg = Release|x64
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Release|x64.Build.0 = Release|x64
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Release|x86.ActiveCfg = Release|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Release|x86.Build.0 = Release|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Debug|x64.ActiveCfg = Debug|x64
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Debug|x64.Build.0 = Debug|x64
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Debug|x86.ActiveCfg = Debug|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Debug|x86.Build.0 = Debug|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Release|Any CPU.ActiveCfg = Release|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Release|x64.ActiveCfg = Release|x64
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Release|x64.Build.0 = Release|x64
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Release|x86.ActiveCfg = Release|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Release|x86.Build.0 = Release|Win32
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Debug|x64.Build.0 = Debug|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Debug|x86.Build.0 = Debug|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Release|x64.ActiveCfg = Release|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Release|x64.Build.0 = Release|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Release|x86.ActiveCfg = Release|Any CPU
+ {901F02A8-8776-4D18-80C9-05C58262C1C7}.Release|x86.Build.0 = Release|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Debug|x64.Build.0 = Debug|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Debug|x86.Build.0 = Debug|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Release|x64.ActiveCfg = Release|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Release|x64.Build.0 = Release|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Release|x86.ActiveCfg = Release|Any CPU
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF}.Release|x86.Build.0 = Release|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Debug|x64.Build.0 = Debug|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Debug|x86.Build.0 = Debug|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Release|x64.ActiveCfg = Release|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Release|x64.Build.0 = Release|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Release|x86.ActiveCfg = Release|Any CPU
+ {0686E907-996A-4D6D-A685-D9C0F932C405}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102} = {8CEC2042-F11C-49F5-A674-2355793B600A}
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ {901F02A8-8776-4D18-80C9-05C58262C1C7} = {B9AA20A4-0F9A-47FB-B3BE-A5BDEA42EFF0}
+ {6CE95C50-9533-4650-8F11-BCE30908DCDF} = {B9AA20A4-0F9A-47FB-B3BE-A5BDEA42EFF0}
+ {0686E907-996A-4D6D-A685-D9C0F932C405} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {160A1D00-1F5B-40F8-A155-621B4459D78F}
+ EndGlobalSection
+EndGlobal
diff --git a/Datadog.Trace.sln b/Datadog.Trace.sln
new file mode 100644
index 0000000000..152efb5d0b
--- /dev/null
+++ b/Datadog.Trace.sln
@@ -0,0 +1,391 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.28803.452
+MinimumVisualStudioVersion = 15.0.26124.0
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Datadog.Trace.ClrProfiler.Native", "src\Datadog.Trace.ClrProfiler.Native\Datadog.Trace.ClrProfiler.Native.vcxproj", "{91B6272F-5780-4C94-8071-DBBA7B4F67F3}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77} = {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Datadog.Trace.ClrProfiler.Native.DLL", "src\Datadog.Trace.ClrProfiler.Native\Datadog.Trace.ClrProfiler.Native.DLL.vcxproj", "{C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77} = {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace", "src\Datadog.Trace\Datadog.Trace.csproj", "{5DFDF781-F24C-45B1-82EF-9125875A80A4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.Tests", "test\Datadog.Trace.Tests\Datadog.Trace.Tests.csproj", "{73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.IntegrationTests", "test\Datadog.Trace.IntegrationTests\Datadog.Trace.IntegrationTests.csproj", "{0434F813-5F94-4195-8A2C-E2E755513822}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.OpenTracing", "src\Datadog.Trace.OpenTracing\Datadog.Trace.OpenTracing.csproj", "{188219D1-D123-46C9-B905-A9ED30E6AAA7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.OpenTracing.Tests", "test\Datadog.Trace.OpenTracing.Tests\Datadog.Trace.OpenTracing.Tests.csproj", "{3BCE5D99-147B-4305-9970-AB0F683A6E8D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.OpenTracing.IntegrationTests", "test\Datadog.Trace.OpenTracing.IntegrationTests\Datadog.Trace.OpenTracing.IntegrationTests.csproj", "{EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.TestHelpers", "test\Datadog.Trace.TestHelpers\Datadog.Trace.TestHelpers.csproj", "{237A1C92-DE9E-4649-961B-BBB7CF0DFE01}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FEBCE7DC-9FD1-48A6-B911-71ABB240A030}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ .gitattributes = .gitattributes
+ .gitignore = .gitignore
+ Datadog.Trace.snk = Datadog.Trace.snk
+ Directory.Build.props = Directory.Build.props
+ GlobalSuppressions.cs = GlobalSuppressions.cs
+ integrations.json = integrations.json
+ LICENSE = LICENSE
+ LICENSE-3rdparty.csv = LICENSE-3rdparty.csv
+ docs\README.md = docs\README.md
+ stylecop.json = stylecop.json
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9E5F0022-0A50-40BF-AC6A-C3078585ECAB}"
+ ProjectSection(SolutionItems) = preProject
+ src\Directory.Build.props = src\Directory.Build.props
+ src\GlobalSuppressions.cs = src\GlobalSuppressions.cs
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8CEC2042-F11C-49F5-A674-2355793B600A}"
+ ProjectSection(SolutionItems) = preProject
+ test\Directory.Build.props = test\Directory.Build.props
+ test\GlobalSuppressions.cs = test\GlobalSuppressions.cs
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.ClrProfiler.Managed", "src\Datadog.Trace.ClrProfiler.Managed\Datadog.Trace.ClrProfiler.Managed.csproj", "{85F35AAF-D102-4960-8B41-3BD9CBD0E77F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Datadog.Trace.ClrProfiler.Native.Tests", "test\Datadog.Trace.ClrProfiler.Native.Tests\Datadog.Trace.ClrProfiler.Native.Tests.vcxproj", "{5728056A-51AA-4FF5-AD0C-E86E44E36102}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.ExampleLibrary", "sample-libs\Samples.ExampleLibrary\Samples.ExampleLibrary.csproj", "{FDB5C8D0-018D-4FF9-9680-C6A5078F819B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.ExampleLibraryTracer", "sample-libs\Samples.ExampleLibraryTracer\Samples.ExampleLibraryTracer.csproj", "{4B243CF1-4269-45C6-A238-1A9BFA58B8CC}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{5D8E1F81-B820-4736-B797-271B0FE787EE}"
+ ProjectSection(SolutionItems) = preProject
+ tools\Directory.Build.props = tools\Directory.Build.props
+ tools\GlobalSuppressions.cs = tools\GlobalSuppressions.cs
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.ClrProfiler.Managed.Tests", "test\Datadog.Trace.ClrProfiler.Managed.Tests\Datadog.Trace.ClrProfiler.Managed.Tests.csproj", "{5B52C0C0-A554-4E53-9D17-B121E78FF919}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample-libs", "sample-libs", "{FA03944C-2391-4C25-8979-2E078A8CE0DD}"
+ ProjectSection(SolutionItems) = preProject
+ sample-libs\Directory.Build.props = sample-libs\Directory.Build.props
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.Shared", "sample-libs\Samples.Shared\Samples.Shared.csproj", "{B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.ClrProfiler.Managed.Loader", "src\Datadog.Trace.ClrProfiler.Managed.Loader\Datadog.Trace.ClrProfiler.Managed.Loader.csproj", "{AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UpdateVendors", "tools\UpdateVendors\UpdateVendors.csproj", "{72FB583A-A1B0-4B5F-8658-617B100DCD8E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Core.Tools", "tools\Datadog.Core.Tools\Datadog.Core.Tools.csproj", "{3BEACB10-89FE-4F74-8022-1A52F223CE82}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.AspNet", "src\Datadog.Trace.AspNet\Datadog.Trace.AspNet.csproj", "{B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PrepareRelease", "tools\PrepareRelease\PrepareRelease.csproj", "{DAA6B000-5BED-4081-B5E0-B698BFB89415}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Datadog.Trace.ClrProfiler.Managed.Core", "src\Datadog.Trace.ClrProfiler.Managed.Core\Datadog.Trace.ClrProfiler.Managed.Core.csproj", "{D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}"
+EndProject
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Datadog.Trace.Ci.Shared", "src\Datadog.Trace.Ci.Shared\Datadog.Trace.Ci.Shared.shproj", "{A1D7653A-C409-414A-B9B0-7879953EBCDD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{E8B98BFD-AFDC-43DA-9CDB-72E3CDC728B3}"
+ ProjectSection(SolutionItems) = preProject
+ docker\Datadog.Trace.ClrProfiler.Native.sh = docker\Datadog.Trace.ClrProfiler.Native.sh
+ docker\native.alpine.dockerfile = docker\native.alpine.dockerfile
+ docker\native.dockerfile = docker\native.dockerfile
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ src\Datadog.Trace.Ci.Shared\Datadog.Trace.Ci.Shared.projitems*{85f35aaf-d102-4960-8b41-3bd9cbd0e77f}*SharedItemsImports = 5
+ src\Datadog.Trace.Ci.Shared\Datadog.Trace.Ci.Shared.projitems*{a1d7653a-c409-414a-b9b0-7879953ebcdd}*SharedItemsImports = 13
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Debug|x64.ActiveCfg = Debug|x64
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Debug|x64.Build.0 = Debug|x64
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Debug|x86.ActiveCfg = Debug|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Debug|x86.Build.0 = Debug|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Release|Any CPU.ActiveCfg = Release|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Release|x64.ActiveCfg = Release|x64
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Release|x64.Build.0 = Release|x64
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Release|x86.ActiveCfg = Release|Win32
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3}.Release|x86.Build.0 = Release|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Debug|x64.ActiveCfg = Debug|x64
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Debug|x64.Build.0 = Debug|x64
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Debug|x86.ActiveCfg = Debug|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Debug|x86.Build.0 = Debug|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Release|Any CPU.ActiveCfg = Release|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Release|x64.ActiveCfg = Release|x64
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Release|x64.Build.0 = Release|x64
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Release|x86.ActiveCfg = Release|Win32
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A}.Release|x86.Build.0 = Release|Win32
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Debug|x64.Build.0 = Debug|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Debug|x86.Build.0 = Debug|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Release|x64.ActiveCfg = Release|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Release|x64.Build.0 = Release|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Release|x86.ActiveCfg = Release|Any CPU
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4}.Release|x86.Build.0 = Release|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Debug|x64.Build.0 = Debug|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Debug|x86.Build.0 = Debug|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Release|x64.ActiveCfg = Release|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Release|x64.Build.0 = Release|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Release|x86.ActiveCfg = Release|Any CPU
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB}.Release|x86.Build.0 = Release|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Debug|x64.Build.0 = Debug|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Debug|x86.Build.0 = Debug|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Release|x64.ActiveCfg = Release|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Release|x64.Build.0 = Release|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Release|x86.ActiveCfg = Release|Any CPU
+ {0434F813-5F94-4195-8A2C-E2E755513822}.Release|x86.Build.0 = Release|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Debug|x64.Build.0 = Debug|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Debug|x86.Build.0 = Debug|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Release|x64.ActiveCfg = Release|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Release|x64.Build.0 = Release|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Release|x86.ActiveCfg = Release|Any CPU
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7}.Release|x86.Build.0 = Release|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Debug|x64.Build.0 = Debug|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Debug|x86.Build.0 = Debug|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Release|x64.ActiveCfg = Release|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Release|x64.Build.0 = Release|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Release|x86.ActiveCfg = Release|Any CPU
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D}.Release|x86.Build.0 = Release|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Debug|x64.Build.0 = Debug|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Debug|x86.Build.0 = Debug|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Release|x64.ActiveCfg = Release|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Release|x64.Build.0 = Release|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Release|x86.ActiveCfg = Release|Any CPU
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F}.Release|x86.Build.0 = Release|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Debug|x64.Build.0 = Debug|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Debug|x86.Build.0 = Debug|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Release|Any CPU.Build.0 = Release|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Release|x64.ActiveCfg = Release|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Release|x64.Build.0 = Release|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Release|x86.ActiveCfg = Release|Any CPU
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01}.Release|x86.Build.0 = Release|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Debug|x64.Build.0 = Debug|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Debug|x86.Build.0 = Debug|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Release|x64.ActiveCfg = Release|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Release|x64.Build.0 = Release|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Release|x86.ActiveCfg = Release|Any CPU
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F}.Release|x86.Build.0 = Release|Any CPU
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Debug|x64.ActiveCfg = Debug|x64
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Debug|x64.Build.0 = Debug|x64
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Debug|x86.ActiveCfg = Debug|Win32
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Debug|x86.Build.0 = Debug|Win32
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Release|Any CPU.ActiveCfg = Release|Win32
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Release|x64.ActiveCfg = Release|x64
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Release|x64.Build.0 = Release|x64
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Release|x86.ActiveCfg = Release|Win32
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102}.Release|x86.Build.0 = Release|Win32
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Debug|x64.Build.0 = Debug|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Debug|x86.Build.0 = Debug|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Release|x64.ActiveCfg = Release|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Release|x64.Build.0 = Release|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Release|x86.ActiveCfg = Release|Any CPU
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B}.Release|x86.Build.0 = Release|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Debug|x64.Build.0 = Debug|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Debug|x86.Build.0 = Debug|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Release|x64.ActiveCfg = Release|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Release|x64.Build.0 = Release|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Release|x86.ActiveCfg = Release|Any CPU
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC}.Release|x86.Build.0 = Release|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Debug|x64.Build.0 = Debug|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Debug|x86.Build.0 = Debug|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Release|x64.ActiveCfg = Release|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Release|x64.Build.0 = Release|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Release|x86.ActiveCfg = Release|Any CPU
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919}.Release|x86.Build.0 = Release|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Debug|x64.Build.0 = Debug|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Debug|x86.Build.0 = Debug|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Release|x64.ActiveCfg = Release|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Release|x64.Build.0 = Release|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Release|x86.ActiveCfg = Release|Any CPU
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964}.Release|x86.Build.0 = Release|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Debug|x64.Build.0 = Debug|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Debug|x86.Build.0 = Debug|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Release|x64.ActiveCfg = Release|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Release|x64.Build.0 = Release|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Release|x86.ActiveCfg = Release|Any CPU
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77}.Release|x86.Build.0 = Release|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Debug|x64.Build.0 = Debug|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Debug|x86.Build.0 = Debug|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Release|x64.ActiveCfg = Release|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Release|x64.Build.0 = Release|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Release|x86.ActiveCfg = Release|Any CPU
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E}.Release|x86.Build.0 = Release|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Debug|x64.Build.0 = Debug|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Debug|x86.Build.0 = Debug|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Release|x64.ActiveCfg = Release|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Release|x64.Build.0 = Release|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Release|x86.ActiveCfg = Release|Any CPU
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82}.Release|x86.Build.0 = Release|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Debug|x64.Build.0 = Debug|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Debug|x86.Build.0 = Debug|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Release|x64.ActiveCfg = Release|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Release|x64.Build.0 = Release|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Release|x86.ActiveCfg = Release|Any CPU
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD}.Release|x86.Build.0 = Release|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Debug|x64.Build.0 = Debug|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Debug|x86.Build.0 = Debug|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Release|x64.ActiveCfg = Release|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Release|x64.Build.0 = Release|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Release|x86.ActiveCfg = Release|Any CPU
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415}.Release|x86.Build.0 = Release|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Debug|x64.Build.0 = Debug|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Debug|x86.Build.0 = Debug|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Release|x64.ActiveCfg = Release|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Release|x64.Build.0 = Release|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Release|x86.ActiveCfg = Release|Any CPU
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {91B6272F-5780-4C94-8071-DBBA7B4F67F3} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ {C0C8D381-D6B9-4C76-9428-F40F2FA93A9A} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ {5DFDF781-F24C-45B1-82EF-9125875A80A4} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ {73A1BE1C-9C8A-43FA-86A8-BF2744B4C1BB} = {8CEC2042-F11C-49F5-A674-2355793B600A}
+ {0434F813-5F94-4195-8A2C-E2E755513822} = {8CEC2042-F11C-49F5-A674-2355793B600A}
+ {188219D1-D123-46C9-B905-A9ED30E6AAA7} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ {3BCE5D99-147B-4305-9970-AB0F683A6E8D} = {8CEC2042-F11C-49F5-A674-2355793B600A}
+ {EFBFC324-B459-4D39-8E19-CE4AD0DBF15F} = {8CEC2042-F11C-49F5-A674-2355793B600A}
+ {237A1C92-DE9E-4649-961B-BBB7CF0DFE01} = {8CEC2042-F11C-49F5-A674-2355793B600A}
+ {85F35AAF-D102-4960-8B41-3BD9CBD0E77F} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ {5728056A-51AA-4FF5-AD0C-E86E44E36102} = {8CEC2042-F11C-49F5-A674-2355793B600A}
+ {FDB5C8D0-018D-4FF9-9680-C6A5078F819B} = {FA03944C-2391-4C25-8979-2E078A8CE0DD}
+ {4B243CF1-4269-45C6-A238-1A9BFA58B8CC} = {FA03944C-2391-4C25-8979-2E078A8CE0DD}
+ {5B52C0C0-A554-4E53-9D17-B121E78FF919} = {8CEC2042-F11C-49F5-A674-2355793B600A}
+ {B4AE8B0F-C2B2-41DF-88BB-D97E267D8964} = {FA03944C-2391-4C25-8979-2E078A8CE0DD}
+ {AB8596C1-CFDA-4A5E-9E9C-74A3DF9AED77} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ {72FB583A-A1B0-4B5F-8658-617B100DCD8E} = {5D8E1F81-B820-4736-B797-271B0FE787EE}
+ {3BEACB10-89FE-4F74-8022-1A52F223CE82} = {5D8E1F81-B820-4736-B797-271B0FE787EE}
+ {B34EDBC7-C5FB-409D-8472-BC7469D6F2BD} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ {DAA6B000-5BED-4081-B5E0-B698BFB89415} = {5D8E1F81-B820-4736-B797-271B0FE787EE}
+ {D95D5E26-F32A-481D-A15A-EF7B3B56D2E0} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ {A1D7653A-C409-414A-B9B0-7879953EBCDD} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {160A1D00-1F5B-40F8-A155-621B4459D78F}
+ EndGlobalSection
+EndGlobal
diff --git a/Datadog.Trace.sln.DotSettings b/Datadog.Trace.sln.DotSettings
new file mode 100644
index 0000000000..725bd2cf47
--- /dev/null
+++ b/Datadog.Trace.sln.DotSettings
@@ -0,0 +1,111 @@
+
+ True
+ Named
+ Required
+ Required
+ Required
+ Required
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ 1
+ True
+ COMPACT
+ True
+ True
+ True
+ NEVER
+ False
+ NEVER
+ False
+ True
+ False
+ True
+ True
+ True
+ CHOP_IF_LONG
+ CHOP_IF_LONG
+ False
+
+ False
+ True
+ False
+ True
+ True
+ True
+ True
+ OS
+ True
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" />
+ <Policy Inspect="False" Prefix="_" Suffix="" Style="aaBb" />
+ <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="Method" Suffix="" Style="AaBb" /></Policy>
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ True
+ True
+ True
+ True
+ True
+ True
+ True
\ No newline at end of file
diff --git a/Datadog.Trace.snk b/Datadog.Trace.snk
new file mode 100644
index 0000000000..b9001cc8c6
Binary files /dev/null and b/Datadog.Trace.snk differ
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000000..22ee0de9b1
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,22 @@
+
+
+ false
+ true
+ false
+ latest
+
+
+ true
+ ..\..\Datadog.Trace.snk
+ true
+ false
+
+
+
+
+
+
+
+
+
+
diff --git a/GlobalSuppressions.cs b/GlobalSuppressions.cs
new file mode 100644
index 0000000000..eb341d382c
--- /dev/null
+++ b/GlobalSuppressions.cs
@@ -0,0 +1,15 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:FieldNamesMustNotBeginWithUnderscore", Justification = "Reviewed.")]
+[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File must have header", Justification = "Reviewed.")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:Prefix local calls with this", Justification = "Reviewed.")]
+[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1200:UsingDirectivesMustBePlacedWithinNamespace", Justification = "Reviewed.")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments must not be followed by blank line", Justification = "Reviewed.")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment must be preceded by blank line", Justification = "Reviewed.")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1501:Statement must not be on a single line", Justification = "Reviewed.")]
+[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1119:StatementMustNotUseUnnecessaryParenthesis", Justification = "Reviewed.")]
diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv
new file mode 100644
index 0000000000..ed96460bac
--- /dev/null
+++ b/LICENSE-3rdparty.csv
@@ -0,0 +1,13 @@
+Component,Origin,License,Copyright
+opentracing-csharp,https://github.com/opentracing/opentracing-csharp,MIT,Copyright 2016-2017 The OpenTracing Authors
+MessagePack-CSharp,https://github.com/neuecc/MessagePack-CSharp,MIT,Copyright (c) 2017 Yoshifumi Kawai and contributors
+liblog,https://github.com/damianh/LibLog,MIT,Copyright (C) 2011-2017 Damian Hickey
+dotnet/runtime,https://github.com/dotnet/runtime,MIT,Copyright (c) .NET Foundation and contributors. All rights reserved.
+clr-samples,https://github.com/Microsoft/clr-samples,MIT,Copyright (c) .NET Foundation and contributors. All rights reserved.
+clrprofiler,https://github.com/MicrosoftArchive/clrprofiler,MIT,Copyright (c) Microsoft Corporation. All rights reserved.
+JSON for Modern C++,https://github.com/nlohmann/json,MIT,Copyright (c) 2013-2018 Niels Lohmann
+Sigil,https://github.com/kevin-montrose/Sigil,MS-PL,2013-2016 Kevin Montrose
+miniutf,https://github.com/dropbox/miniutf,MIT,"Copyright (c) 2013 Dropbox, Inc."
+Serilog,https://github.com/serilog/serilog,Apache-2.0,"Copyright (c) 2013-2018 Serilog Contributors"
+Serilog.Sinks.File,https://github.com/serilog/serilog-sinks-file,Apache-2.0,"Copyright (c) 2016 Serilog Contributors"
+opentracing-contrib/csharp-netcore,https://github.com/opentracing-contrib/csharp-netcore,Apache-2.0,
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000000..90b7bbbcdc
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,4 @@
+Datadog .NET Tracer for APM (dd-trace-dotnet)
+Copyright 2017 Datadog, Inc.
+
+This product includes software developed at Datadog (https://www.datadoghq.com/).
\ No newline at end of file
diff --git a/datadog-logo-256x256.png b/datadog-logo-256x256.png
new file mode 100644
index 0000000000..ad0bd74440
Binary files /dev/null and b/datadog-logo-256x256.png differ
diff --git a/datadog-logo-64x64.png b/datadog-logo-64x64.png
new file mode 100644
index 0000000000..d880a906c8
Binary files /dev/null and b/datadog-logo-64x64.png differ
diff --git a/devenv.bat b/devenv.bat
new file mode 100644
index 0000000000..6ad780e8bc
--- /dev/null
+++ b/devenv.bat
@@ -0,0 +1,87 @@
+@echo off
+rem This batch script sets up the development environment
+rem by enabling the Profiler API and starting Visual Studio.
+rem Any process started by VS will inherit the environment variables,
+rem enabling the profiler for apps run from VS, including while debugging.
+
+rem Set default values
+set profiler_platform=x64
+set profiler_configuration=Debug
+set start_visual_studio=true
+set vs_sln_name=Datadog.Trace.sln
+
+:next_argument
+set devenv_arg1=%1
+
+if not "%devenv_arg1%" == "" (
+ if /i "%devenv_arg1%" == "Debug" (
+ set profiler_configuration=Debug
+ ) else if /i "%devenv_arg1%" == "Release" (
+ set profiler_configuration=Release
+ ) else if /i "%devenv_arg1%" == "x64" (
+ set profiler_platform=x64
+ ) else if /i "%devenv_arg1%" == "x86" (
+ set profiler_platform=x86
+ ) else if /i "%devenv_arg1%" == "vs+" (
+ set start_visual_studio=true
+ ) else if /i "%devenv_arg1%" == "vs-" (
+ set start_visual_studio=false
+ ) else (
+ echo Invalid option: "%devenv_arg1%".
+ goto show_usage
+ )
+
+ shift
+ goto next_argument
+)
+
+echo Enabling profiler for "%profiler_configuration%/%profiler_platform%".
+
+rem Enable .NET Framework Profiling API
+SET COR_ENABLE_PROFILING=1
+SET COR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
+SET COR_PROFILER_PATH=%~dp0\src\Datadog.Trace.ClrProfiler.Native\bin\%profiler_configuration%\%profiler_platform%\Datadog.Trace.ClrProfiler.Native.dll
+
+rem Enable .NET Core Profiling API
+SET CORECLR_ENABLE_PROFILING=1
+SET CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
+SET CORECLR_PROFILER_PATH=%~dp0\src\Datadog.Trace.ClrProfiler.Native\bin\%profiler_configuration%\%profiler_platform%\Datadog.Trace.ClrProfiler.Native.dll
+
+rem Don't attach the profiler to these processes
+SET DD_PROFILER_EXCLUDE_PROCESSES=devenv.exe;Microsoft.ServiceHub.Controller.exe;ServiceHub.Host.CLR.exe;ServiceHub.TestWindowStoreHost.exe;ServiceHub.DataWarehouseHost.exe;sqlservr.exe;VBCSCompiler.exe;iisexpresstray.exe;msvsmon.exe
+
+rem Set dotnet tracer home path
+SET DD_DOTNET_TRACER_HOME=%~dp0
+SET DD_INTEGRATIONS=%DD_DOTNET_TRACER_HOME%\integrations.json
+
+if "%start_visual_studio%" == "true" (
+ echo Starting Visual Studio...
+
+ IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Professional\Common7\IDE\devenv.exe" (
+ START "Visual Studio" "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Professional\Common7\IDE\devenv.exe" "%~dp0\%vs_sln_name%"
+ ) ELSE IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe" (
+ START "Visual Studio" "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe" "%~dp0\%vs_sln_name%"
+ ) ELSE IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\Common7\IDE\devenv.exe" (
+ START "Visual Studio" "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\Common7\IDE\devenv.exe" "%~dp0\%vs_sln_name%"
+ ) ELSE (
+ START "Visual Studio" "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.exe" "%~dp0\%vs_sln_name%"
+ )
+)
+goto end
+
+:show_usage
+echo Usage: %0 [Release^|Debug] [x64^|x86] [vs+^|vs-]
+echo All arguments are optional and can be provided in any order.
+echo If an argument is provided multiple times, the last value wins.
+echo The default configuration is "Release".
+echo The default platform is "x64".
+echo Visual Studio is started unless "vs-" is specified.
+
+:end
+rem Clear temporary values
+set profiler_platform=
+set profiler_configuration=
+set start_visual_studio=
+set vs_sln_name=
+set devenv_arg1=
+set devenv_arg1_sub7=
\ No newline at end of file
diff --git a/docker/Datadog.Trace.ClrProfiler.Native.sh b/docker/Datadog.Trace.ClrProfiler.Native.sh
new file mode 100755
index 0000000000..d2e7aa417b
--- /dev/null
+++ b/docker/Datadog.Trace.ClrProfiler.Native.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -euxo pipefail
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+
+cd "$DIR/.."
+
+PUBLISH_OUTPUT="$( pwd )/src/bin/managed-publish/netstandard2.0"
+
+cd src/Datadog.Trace.ClrProfiler.Native
+mkdir -p obj/Debug/x64
+(cd obj/Debug/x64 && cmake ../../.. && make)
+
+mkdir -p bin/Debug/x64
+cp -f obj/Debug/x64/Datadog.Trace.ClrProfiler.Native.so bin/Debug/x64/Datadog.Trace.ClrProfiler.Native.so
+
+mkdir -p bin/Debug/x64/netstandard2.0
+cp -f $PUBLISH_OUTPUT/*.dll bin/Debug/x64/netstandard2.0/
diff --git a/docker/native.alpine.dockerfile b/docker/native.alpine.dockerfile
new file mode 100644
index 0000000000..e2e6e06330
--- /dev/null
+++ b/docker/native.alpine.dockerfile
@@ -0,0 +1,19 @@
+FROM alpine:3.11
+
+RUN apk update && apk upgrade
+
+RUN apk add --no-cache --update clang cmake git bash make alpine-sdk
+
+# libraries
+
+RUN mkdir -p /opt
+ENV CXX=clang++
+ENV CC=clang-9
+
+# - nlohmann/json
+RUN cd /opt && git clone --depth 1 --branch v3.3.0 https://github.com/nlohmann/json.git
+# RUN cd /opt/json && cmake -G Ninja . && cmake --build .
+
+# - re2
+RUN cd /opt && git clone --depth 1 --branch 2018-10-01 https://github.com/google/re2.git
+RUN cd /opt/re2 && env CXXFLAGS="-O3 -g -fPIC" make
\ No newline at end of file
diff --git a/docker/native.dockerfile b/docker/native.dockerfile
new file mode 100644
index 0000000000..b3485c753e
--- /dev/null
+++ b/docker/native.dockerfile
@@ -0,0 +1,56 @@
+FROM ubuntu:14.04
+
+RUN apt-get update && \
+ apt-get install -y \
+ git \
+ wget
+
+RUN echo "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.9 main" | sudo tee /etc/apt/sources.list.d/llvm.list
+RUN wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
+RUN sudo apt-get update
+
+RUN sudo apt-get install -y \
+ cmake \
+ llvm-3.9 \
+ clang-3.9 \
+ lldb-3.9 \
+ liblldb-3.9-dev \
+ libunwind8 \
+ libunwind8-dev \
+ gettext \
+ libicu-dev \
+ liblttng-ust-dev \
+ libcurl4-openssl-dev \
+ libssl-dev \
+ libnuma-dev \
+ libkrb5-dev
+
+RUN cd /usr/lib/llvm-3.9/lib && ln -s ../../x86_64-linux-gnu/liblldb-3.9.so.1 liblldb-3.9.so.1
+
+RUN apt-get update && apt-get install -y \
+ python-software-properties \
+ software-properties-common
+
+RUN add-apt-repository ppa:ubuntu-toolchain-r/test && \
+ apt-get update && \
+ apt-get install -y \
+ curl \
+ ninja-build
+# cmake
+RUN apt-get remove -y cmake && \
+ curl -o /tmp/cmake.sh https://cmake.org/files/v3.12/cmake-3.12.3-Linux-x86_64.sh && \
+ sh /tmp/cmake.sh --prefix=/usr/local --exclude-subdir --skip-license
+
+# libraries
+
+RUN mkdir -p /opt
+ENV CXX=clang++-3.9
+ENV CC=clang-3.9
+
+# - nlohmann/json
+RUN cd /opt && git clone --depth 1 --branch v3.3.0 https://github.com/nlohmann/json.git
+# RUN cd /opt/json && cmake -G Ninja . && cmake --build .
+
+# - re2
+RUN cd /opt && git clone --depth 1 --branch 2018-10-01 https://github.com/google/re2.git
+RUN cd /opt/re2 && env CXXFLAGS="-O3 -g -fPIC" make
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
new file mode 100644
index 0000000000..5096f6f6e1
--- /dev/null
+++ b/docs/CHANGELOG.md
@@ -0,0 +1,29 @@
+# Datadog .NET Tracer (`dd-trace-dotnet`) Release Notes
+
+## [Release 1.10.0](https://github.com/DataDog/dd-trace-dotnet/releases/tag/v1.10.0)
+
+### New
+- Add ASP.NET Core MVC 3 integration (#555)
+- Add `IDbCommand` instrumentation to the ADO.NET integration (#562)
+
+### Fixed
+- Fix `DD_LOGS_INJECTION` crash with the ASP.NET integration (#551)
+- Fix scope creation failing in ASP.NET MVC integration when URL is empty (#553)
+- Fix crash when Profiler and NuGet package versions do not match (#570)
+- Add missing tags to GraphQL integration (#547)
+- Get the instrumented type instead of using build-time `typeof()` in `HttpMessageHandler` integration (#558)
+
+### Builds and Tests
+- Enable `Samples.MySql` test in CI (#548)
+- Reduce permutations of minors in package versions tool (#545)
+- Refactor "expectations" test framework (#554)
+- Enable prerelease version tags (#556)
+- Make timing and statistics tests less flaky (#559)
+- Clean up `MockTraceAgent`, add event-based API (#501)
+- Clean up project settings (#565)
+
+[All commits](https://github.com/DataDog/dd-trace-dotnet/compare/v1.9.0...v1.10.0) | [Full diff](https://github.com/DataDog/dd-trace-dotnet/compare/v1.9.0..v1.10.0)
+
+---
+
+### Release notes for releases before 1.10.0 can be found in the [releases page](https://github.com/DataDog/dd-trace-dotnet/releases) on GitHub.
\ No newline at end of file
diff --git a/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000000..c55065f9c8
--- /dev/null
+++ b/docs/CODE_OF_CONDUCT.md
@@ -0,0 +1,76 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at info@datadoghq.com. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
\ No newline at end of file
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
new file mode 100644
index 0000000000..9016a7907a
--- /dev/null
+++ b/docs/CONTRIBUTING.md
@@ -0,0 +1,6 @@
+As an open source project we welcome contributions of many forms. Please reach out before starting
+work on any major code changes. This will ensure we avoid duplicating work, or that
+your code can't be merged due to a rapidly changing code base. If you would like support
+for a library that is not listed, [contact support][1] to share a request.
+
+[1]: https://docs.datadoghq.com/help
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000000..03a77f4417
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,129 @@
+# .NET Tracer for Datadog APM
+
+## Installation and Usage
+
+Please [read our documentation](https://docs.datadoghq.com/tracing/setup/dotnet) for instructions on setting up .NET tracing and details about supported frameworks.
+
+## Downloads
+Package|Download
+-|-
+Windows and Linux Installers|[See releases](https://github.com/DataDog/dd-trace-dotnet/releases)
+`Datadog.Trace`|[](https://www.nuget.org/packages/Datadog.Trace)
+`Datadog.Trace.OpenTracing`|[](https://www.nuget.org/packages/Datadog.Trace.OpenTracing)
+
+## Build Status on `master`
+
+Pipeline | Build Status
+------------------|-------------
+Unit tests | [](https://dev.azure.com/datadog-apm/dd-trace-dotnet/_build/latest?definitionId=28&branchName=master)
+Integration tests | [](https://dev.azure.com/datadog-apm/dd-trace-dotnet/_build/latest?definitionId=27&branchName=master)
+
+# Development
+
+## Components
+
+**[Datadog Agent](https://github.com/DataDog/datadog-agent)**: A service that runs on your application servers, accepting trace data from the Datadog Tracer and sending it to Datadog. The Agent is not part of this repo; it's the same Agent to which all Datadog tracers (e.g. Go, Python, Java, Ruby) send data.
+
+**[Datadog .NET Tracer](https://github.com/DataDog/dd-trace-dotnet)**: This repository. A set of .NET libraries that let you trace any piece of your .NET code. Supports manual instrumentation and can automatically instrument supported libraries out-of-the-box.
+
+## Windows
+
+### Minimum requirements
+
+- [Visual Studio 2019](https://visualstudio.microsoft.com/downloads/) or newer
+ - Workloads
+ - Desktop development with C++
+ - .NET desktop development
+ - .NET Core cross-platform development
+ - Optional: ASP.NET and web development (to build samples)
+ - Individual components
+ - .NET Framework 4.7 targeting pack
+- [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download/dotnet-core/3.1)
+- Optional: [.NET Core 2.1 Runtime](https://dotnet.microsoft.com/download/dotnet-core/2.1) to test in .NET Core 2.1 locally.
+- Optional: [.NET Core 3.0 Runtime](https://dotnet.microsoft.com/download/dotnet-core/3.0) to test in .NET Core 3.0 locally.
+- Optional: [nuget.exe CLI](https://www.nuget.org/downloads) v5.3 or newer
+- Optional: [WiX Toolset 3.11.1](http://wixtoolset.org/releases/) or newer to build Windows installer (msi)
+ - Requires .NET Framework 3.5 SP2 (install from Windows Features control panel: `OptionalFeatures.exe`)
+ - [WiX Toolset Visual Studio Extension](https://wixtoolset.org/releases/) to build installer from Visual Studio
+- Optional: [Docker for Windows](https://docs.docker.com/docker-for-windows/) to build Linux binaries and run integration tests on Linux containers. See [section on Docker Compose](#building-and-running-tests-with-docker-compose).
+ - Requires Windows 10 (1607 Anniversary Update, Build 14393 or newer)
+
+Microsoft provides [evaluation developer VMs](https://developer.microsoft.com/en-us/windows/downloads/virtual-machines) with Windows 10 and Visual Studio pre-installed.
+
+### Building from a command line
+
+From a _Developer Command Prompt for VS 2019_:
+
+```cmd
+rem Restore NuGet packages
+rem nuget.exe is required for command line restore because msbuild doesn't support packages.config
+rem (see https://github.com/NuGet/Home/issues/7386)
+nuget restore Datadog.Trace.sln
+
+rem Build C# projects (Platform: always AnyCPU)
+msbuild Datadog.Trace.proj /t:BuildCsharp /p:Configuration=Release
+
+rem Build NuGet packages
+dotnet pack src\Datadog.Trace\Datadog.Trace.csproj
+dotnet pack src\Datadog.Trace.OpenTracing\Datadog.Trace.OpenTracing.csproj
+
+rem Build C++ projects
+rem The native profiler depends on the Datadog.Trace.ClrProfiler.Managed.Loader C# project so be sure that is built first
+msbuild Datadog.Trace.proj /t:BuildCpp /p:Configuration=Release;Platform=x64
+msbuild Datadog.Trace.proj /t:BuildCpp /p:Configuration=Release;Platform=x86
+
+rem Build MSI installer for Windows x64 (supports both x64 and x86 apps)
+msbuild Datadog.Trace.proj /t:msi /p:Configuration=Release;Platform=x64
+
+rem Build MSI installer for Windows x86 (supports x86 apps only)
+msbuild Datadog.Trace.proj /t:msi /p:Configuration=Release;Platform=x86
+
+rem Build tracer home directory for Windows.
+rem Valid values for property `Platform` are `x64`, `x86`, and `All`.
+msbuild Datadog.Trace.proj /t:CreateHomeDirectory /p:Configuration=Release;Platform=All
+```
+
+## Linux
+
+### Minimum requirements
+
+To build C# projects and NuGet packages only
+- [.NET Core SDK 3.1](https://dotnet.microsoft.com/download/dotnet-core/3.1)
+
+To build everything and run integration tests
+- [Docker Compose](https://docs.docker.com/compose/install/)
+
+### Building and running tests with Docker Compose
+
+You can use [Docker Compose](https://docs.docker.com/compose/) with Linux containers to build Linux binaries and run the test suites. This works on both Linux and Windows hosts.
+
+```bash
+# build C# projects
+docker-compose run build
+
+# build C++ project
+docker-compose run Profiler
+
+# run integration tests
+docker-compose run IntegrationTests
+```
+
+## Further Reading
+
+Datadog APM
+- [Datadog APM](https://docs.datadoghq.com/tracing/)
+- [Datadog APM - Tracing .NET Applications](https://docs.datadoghq.com/tracing/setup/dotnet/)
+- [Datadog APM - Advanced Usage](https://docs.datadoghq.com/tracing/advanced_usage/?tab=dotnet)
+
+Microsoft .NET Profiling APIs
+- [Profiling API](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/)
+- [Metadata API](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/metadata/)
+- [The Book of the Runtime - Profiling](https://github.com/dotnet/coreclr/blob/master/Documentation/botr/profiling.md)
+
+OpenTracing
+- [OpenTracing documentation](https://github.com/opentracing/opentracing-csharp)
+- [OpenTracing terminology](https://github.com/opentracing/specification/blob/master/specification.md)
+
+## Get in touch
+
+If you have questions, feedback, or feature requests, reach our [support](https://docs.datadoghq.com/help).
diff --git a/git-clean.cmd b/git-clean.cmd
new file mode 100644
index 0000000000..3092bf2e1c
--- /dev/null
+++ b/git-clean.cmd
@@ -0,0 +1 @@
+git clean -dxf -e *.user -e *.bat -e *.cmd -e packages/ -e .vs/ -e .vscode/
\ No newline at end of file
diff --git a/integrations.json b/integrations.json
new file mode 100644
index 0000000000..a920533505
--- /dev/null
+++ b/integrations.json
@@ -0,0 +1,2395 @@
+[
+ {
+ "name": "AspNetMvc",
+ "method_replacements": [
+ {
+ "caller": {
+ "assembly": "System.Web.Mvc"
+ },
+ "target": {
+ "assembly": "System.Web.Mvc",
+ "type": "System.Web.Mvc.Async.IAsyncActionInvoker",
+ "method": "BeginInvokeAction",
+ "signature_types": [
+ "System.IAsyncResult",
+ "System.Web.Mvc.ControllerContext",
+ "System.String",
+ "System.AsyncCallback",
+ "System.Object"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 5,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AspNetMvcIntegration",
+ "method": "BeginInvokeAction",
+ "signature": "00 08 1C 1C 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {
+ "assembly": "System.Web.Mvc"
+ },
+ "target": {
+ "assembly": "System.Web.Mvc",
+ "type": "System.Web.Mvc.Async.IAsyncActionInvoker",
+ "method": "EndInvokeAction",
+ "signature_types": [
+ "System.Boolean",
+ "System.IAsyncResult"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 5,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AspNetMvcIntegration",
+ "method": "EndInvokeAction",
+ "signature": "00 05 02 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "AspNetWebApi2",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Web.Http",
+ "type": "System.Web.Http.Controllers.IHttpController",
+ "method": "ExecuteAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Web.Http.Controllers.HttpControllerContext",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 5,
+ "minimum_minor": 1,
+ "minimum_patch": 0,
+ "maximum_major": 5,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AspNetWebApi2Integration",
+ "method": "ExecuteAsync",
+ "signature": "00 06 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "DbCommand",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.Common.DbDataReader"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteReader",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.Common.DbDataReader"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteReader",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.Common.DbDataReader"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteReader",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.Common.DbDataReader",
+ "System.Data.CommandBehavior"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteReaderWithBehavior",
+ "signature": "00 05 1C 1C 08 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.Common.DbDataReader",
+ "System.Data.CommandBehavior"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteReaderWithBehavior",
+ "signature": "00 05 1C 1C 08 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.Common.DbDataReader",
+ "System.Data.CommandBehavior"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteReaderWithBehavior",
+ "signature": "00 05 1C 1C 08 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteReaderAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Data.CommandBehavior",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteReaderAsync",
+ "signature": "00 06 1C 1C 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteReaderAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Data.CommandBehavior",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteReaderAsync",
+ "signature": "00 06 1C 1C 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteReaderAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Data.CommandBehavior",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteReaderAsync",
+ "signature": "00 06 1C 1C 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteNonQuery",
+ "signature_types": [
+ "System.Int32"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteNonQuery",
+ "signature": "00 04 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteNonQuery",
+ "signature_types": [
+ "System.Int32"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteNonQuery",
+ "signature": "00 04 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteNonQuery",
+ "signature_types": [
+ "System.Int32"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteNonQuery",
+ "signature": "00 04 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteNonQueryAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteNonQueryAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteNonQueryAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteNonQueryAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteNonQueryAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteNonQueryAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteScalar",
+ "signature_types": [
+ "System.Object"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteScalar",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteScalar",
+ "signature_types": [
+ "System.Object"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteScalar",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteScalar",
+ "signature_types": [
+ "System.Object"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteScalar",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteScalarAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteScalarAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteScalarAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteScalarAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.Common.DbCommand",
+ "method": "ExecuteScalarAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.DbCommandIntegration",
+ "method": "ExecuteScalarAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "ElasticsearchNet5",
+ "method_replacements": [
+ {
+ "caller": {
+ "assembly": "Elasticsearch.Net"
+ },
+ "target": {
+ "assembly": "Elasticsearch.Net",
+ "type": "Elasticsearch.Net.IRequestPipeline",
+ "method": "CallElasticsearch",
+ "signature_types": [
+ "Elasticsearch.Net.ElasticsearchResponse`1",
+ "Elasticsearch.Net.RequestData"
+ ],
+ "minimum_major": 5,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 5,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.ElasticsearchNet5Integration",
+ "method": "CallElasticsearch",
+ "signature": "10 01 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {
+ "assembly": "Elasticsearch.Net"
+ },
+ "target": {
+ "assembly": "Elasticsearch.Net",
+ "type": "Elasticsearch.Net.IRequestPipeline",
+ "method": "CallElasticsearchAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1>",
+ "Elasticsearch.Net.RequestData",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 5,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 5,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.ElasticsearchNet5Integration",
+ "method": "CallElasticsearchAsync",
+ "signature": "10 01 06 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "ElasticsearchNet6",
+ "method_replacements": [
+ {
+ "caller": {
+ "assembly": "Elasticsearch.Net"
+ },
+ "target": {
+ "assembly": "Elasticsearch.Net",
+ "type": "Elasticsearch.Net.IRequestPipeline",
+ "method": "CallElasticsearch",
+ "signature_types": [
+ "T",
+ "Elasticsearch.Net.RequestData"
+ ],
+ "minimum_major": 6,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 6,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.ElasticsearchNet6Integration",
+ "method": "CallElasticsearch",
+ "signature": "10 01 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {
+ "assembly": "Elasticsearch.Net"
+ },
+ "target": {
+ "assembly": "Elasticsearch.Net",
+ "type": "Elasticsearch.Net.IRequestPipeline",
+ "method": "CallElasticsearchAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "Elasticsearch.Net.RequestData",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 6,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 6,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.ElasticsearchNet6Integration",
+ "method": "CallElasticsearchAsync",
+ "signature": "10 01 06 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "GraphQL",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "GraphQL",
+ "type": "GraphQL.Validation.IDocumentValidator",
+ "method": "Validate",
+ "signature_types": [
+ "GraphQL.Validation.IValidationResult",
+ "System.String",
+ "GraphQL.Types.ISchema",
+ "GraphQL.Language.AST.Document",
+ "System.Collections.Generic.IEnumerable`1",
+ "_",
+ "GraphQL.Inputs"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 3,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.GraphQLIntegration",
+ "method": "Validate",
+ "signature": "00 0A 1C 1C 1C 1C 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "GraphQL",
+ "type": "GraphQL.Execution.IExecutionStrategy",
+ "method": "ExecuteAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "GraphQL.Execution.ExecutionContext"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 3,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.GraphQLIntegration",
+ "method": "ExecuteAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "HttpMessageHandler",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Net.Http",
+ "type": "System.Net.Http.HttpMessageHandler",
+ "method": "SendAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Net.Http.HttpRequestMessage",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.HttpMessageHandlerIntegration",
+ "method": "HttpMessageHandler_SendAsync",
+ "signature": "00 06 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Net.Http",
+ "type": "System.Net.Http.HttpClientHandler",
+ "method": "SendAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Net.Http.HttpRequestMessage",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.HttpMessageHandlerIntegration",
+ "method": "HttpClientHandler_SendAsync",
+ "signature": "00 06 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "IDbCommand",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.IDataReader"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteReader",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.IDataReader"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteReader",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.IDataReader"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteReader",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.IDataReader",
+ "System.Data.CommandBehavior"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteReaderWithBehavior",
+ "signature": "00 05 1C 1C 08 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.IDataReader",
+ "System.Data.CommandBehavior"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteReaderWithBehavior",
+ "signature": "00 05 1C 1C 08 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.IDataReader",
+ "System.Data.CommandBehavior"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteReaderWithBehavior",
+ "signature": "00 05 1C 1C 08 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteNonQuery",
+ "signature_types": [
+ "System.Int32"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteNonQuery",
+ "signature": "00 04 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteNonQuery",
+ "signature_types": [
+ "System.Int32"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteNonQuery",
+ "signature": "00 04 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteNonQuery",
+ "signature_types": [
+ "System.Int32"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteNonQuery",
+ "signature": "00 04 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteScalar",
+ "signature_types": [
+ "System.Object"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteScalar",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.Common",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteScalar",
+ "signature_types": [
+ "System.Object"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteScalar",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "netstandard",
+ "type": "System.Data.IDbCommand",
+ "method": "ExecuteScalar",
+ "signature_types": [
+ "System.Object"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.IDbCommandIntegration",
+ "method": "ExecuteScalar",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "MongoDb",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "MongoDB.Driver.Core",
+ "type": "MongoDB.Driver.Core.WireProtocol.IWireProtocol",
+ "method": "Execute",
+ "signature_types": [
+ "System.Void",
+ "MongoDB.Driver.Core.Connections.IConnection",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 2,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.MongoDbIntegration",
+ "method": "Execute",
+ "signature": "00 06 01 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "MongoDB.Driver.Core",
+ "type": "MongoDB.Driver.Core.WireProtocol.IWireProtocol`1",
+ "method": "Execute",
+ "signature_types": [
+ "T",
+ "MongoDB.Driver.Core.Connections.IConnection",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 2,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.MongoDbIntegration",
+ "method": "ExecuteGeneric",
+ "signature": "00 06 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "MongoDB.Driver.Core",
+ "type": "MongoDB.Driver.Core.WireProtocol.IWireProtocol",
+ "method": "ExecuteAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task",
+ "MongoDB.Driver.Core.Connections.IConnection",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 1,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.MongoDbIntegration",
+ "method": "ExecuteAsync",
+ "signature": "00 06 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "MongoDB.Driver.Core",
+ "type": "MongoDB.Driver.Core.WireProtocol.IWireProtocol`1",
+ "method": "ExecuteAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "MongoDB.Driver.Core.Connections.IConnection",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 1,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.MongoDbIntegration",
+ "method": "ExecuteAsyncGeneric",
+ "signature": "00 06 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "NpgsqlCommand",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "Npgsql",
+ "type": "Npgsql.NpgsqlCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "Npgsql.NpgsqlDataReader"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.NpgsqlCommandIntegration",
+ "method": "ExecuteReader",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "Npgsql",
+ "type": "Npgsql.NpgsqlCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "Npgsql.NpgsqlDataReader",
+ "System.Data.CommandBehavior"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.NpgsqlCommandIntegration",
+ "method": "ExecuteReaderWithBehavior",
+ "signature": "00 05 1C 1C 08 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "Npgsql",
+ "type": "Npgsql.NpgsqlCommand",
+ "method": "ExecuteReaderAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.NpgsqlCommandIntegration",
+ "method": "ExecuteReaderAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "Npgsql",
+ "type": "Npgsql.NpgsqlCommand",
+ "method": "ExecuteReaderAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Data.CommandBehavior",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.NpgsqlCommandIntegration",
+ "method": "ExecuteReaderAsyncWithBehaviorAndCancellation",
+ "signature": "00 06 1C 1C 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "Npgsql",
+ "type": "Npgsql.NpgsqlCommand",
+ "method": "ExecuteNonQuery",
+ "signature_types": [
+ "System.Int32"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.NpgsqlCommandIntegration",
+ "method": "ExecuteNonQuery",
+ "signature": "00 04 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "Npgsql",
+ "type": "Npgsql.NpgsqlCommand",
+ "method": "ExecuteNonQueryAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.NpgsqlCommandIntegration",
+ "method": "ExecuteNonQueryAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "Npgsql",
+ "type": "Npgsql.NpgsqlCommand",
+ "method": "ExecuteScalar",
+ "signature_types": [
+ "System.Object"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.NpgsqlCommandIntegration",
+ "method": "ExecuteScalar",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "Npgsql.NpgsqlCommand",
+ "method": "ExecuteScalarAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.NpgsqlCommandIntegration",
+ "method": "ExecuteScalarAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.SqlClient",
+ "type": "Npgsql.NpgsqlCommand",
+ "method": "ExecuteScalarAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.NpgsqlCommandIntegration",
+ "method": "ExecuteScalarAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "ServiceStackRedis",
+ "method_replacements": [
+ {
+ "caller": {
+ "assembly": "ServiceStack.Redis"
+ },
+ "target": {
+ "assembly": "ServiceStack.Redis",
+ "type": "ServiceStack.Redis.RedisNativeClient",
+ "method": "SendReceive",
+ "signature_types": [
+ "T",
+ "System.Byte[][]",
+ "System.Func`1",
+ "System.Action`1>",
+ "System.Boolean"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 5,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.ServiceStackRedisIntegration",
+ "method": "SendReceive",
+ "signature": "10 01 08 1E 00 1C 1D 1D 05 1C 1C 02 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "SqlCommand",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.SqlClient.SqlDataReader"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteReader",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.SqlClient",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.SqlClient.SqlDataReader"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteReader",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.SqlClient.SqlDataReader",
+ "System.Data.CommandBehavior"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteReaderWithBehavior",
+ "signature": "00 05 1C 1C 08 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.SqlClient",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteReader",
+ "signature_types": [
+ "System.Data.SqlClient.SqlDataReader",
+ "System.Data.CommandBehavior"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteReaderWithBehavior",
+ "signature": "00 05 1C 1C 08 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteReaderAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Data.CommandBehavior",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteReaderAsync",
+ "signature": "00 06 1C 1C 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.SqlClient",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteReaderAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Data.CommandBehavior",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteReaderAsync",
+ "signature": "00 06 1C 1C 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteNonQuery",
+ "signature_types": [
+ "System.Int32"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteNonQuery",
+ "signature": "00 04 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.SqlClient",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteNonQuery",
+ "signature_types": [
+ "System.Int32"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteNonQuery",
+ "signature": "00 04 08 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteNonQueryAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteNonQueryAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.SqlClient",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteNonQueryAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteNonQueryAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteScalar",
+ "signature_types": [
+ "System.Object"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteScalar",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.SqlClient",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteScalar",
+ "signature_types": [
+ "System.Object"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteScalar",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteScalarAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteScalarAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Data.SqlClient",
+ "type": "System.Data.SqlClient.SqlCommand",
+ "method": "ExecuteScalarAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "System.Threading.CancellationToken"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.AdoNet.SqlCommandIntegration",
+ "method": "ExecuteScalarAsync",
+ "signature": "00 05 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "StackExchangeRedis",
+ "method_replacements": [
+ {
+ "caller": {
+ "assembly": "StackExchange.Redis"
+ },
+ "target": {
+ "assembly": "StackExchange.Redis",
+ "type": "StackExchange.Redis.ConnectionMultiplexer",
+ "method": "ExecuteSyncImpl",
+ "signature_types": [
+ "T",
+ "StackExchange.Redis.Message",
+ "StackExchange.Redis.ResultProcessor`1",
+ "StackExchange.Redis.ServerEndPoint"
+ ],
+ "minimum_major": 1,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis.ConnectionMultiplexer",
+ "method": "ExecuteSyncImpl",
+ "signature": "10 01 07 1E 00 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {
+ "assembly": "StackExchange.Redis.StrongName"
+ },
+ "target": {
+ "assembly": "StackExchange.Redis.StrongName",
+ "type": "StackExchange.Redis.ConnectionMultiplexer",
+ "method": "ExecuteSyncImpl",
+ "signature_types": [
+ "T",
+ "StackExchange.Redis.Message",
+ "StackExchange.Redis.ResultProcessor`1",
+ "StackExchange.Redis.ServerEndPoint"
+ ],
+ "minimum_major": 1,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis.ConnectionMultiplexer",
+ "method": "ExecuteSyncImpl",
+ "signature": "10 01 07 1E 00 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {
+ "assembly": "StackExchange.Redis"
+ },
+ "target": {
+ "assembly": "StackExchange.Redis",
+ "type": "StackExchange.Redis.ConnectionMultiplexer",
+ "method": "ExecuteAsyncImpl",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "StackExchange.Redis.Message",
+ "StackExchange.Redis.ResultProcessor`1",
+ "System.Object",
+ "StackExchange.Redis.ServerEndPoint"
+ ],
+ "minimum_major": 1,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis.ConnectionMultiplexer",
+ "method": "ExecuteAsyncImpl",
+ "signature": "10 01 08 1C 1C 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {
+ "assembly": "StackExchange.Redis.StrongName"
+ },
+ "target": {
+ "assembly": "StackExchange.Redis.StrongName",
+ "type": "StackExchange.Redis.ConnectionMultiplexer",
+ "method": "ExecuteAsyncImpl",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "StackExchange.Redis.Message",
+ "StackExchange.Redis.ResultProcessor`1",
+ "System.Object",
+ "StackExchange.Redis.ServerEndPoint"
+ ],
+ "minimum_major": 1,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis.ConnectionMultiplexer",
+ "method": "ExecuteAsyncImpl",
+ "signature": "10 01 08 1C 1C 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {
+ "assembly": "StackExchange.Redis"
+ },
+ "target": {
+ "assembly": "StackExchange.Redis",
+ "type": "StackExchange.Redis.RedisBase",
+ "method": "ExecuteAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "StackExchange.Redis.Message",
+ "StackExchange.Redis.ResultProcessor`1",
+ "StackExchange.Redis.ServerEndPoint"
+ ],
+ "minimum_major": 1,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis.RedisBatch",
+ "method": "ExecuteAsync",
+ "signature": "10 01 07 1C 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {
+ "assembly": "StackExchange.Redis.StrongName"
+ },
+ "target": {
+ "assembly": "StackExchange.Redis.StrongName",
+ "type": "StackExchange.Redis.RedisBase",
+ "method": "ExecuteAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "StackExchange.Redis.Message",
+ "StackExchange.Redis.ResultProcessor`1",
+ "StackExchange.Redis.ServerEndPoint"
+ ],
+ "minimum_major": 1,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis.RedisBatch",
+ "method": "ExecuteAsync",
+ "signature": "10 01 07 1C 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "Wcf",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.ServiceModel",
+ "type": "System.ServiceModel.Dispatcher.ChannelHandler",
+ "method": "HandleRequest",
+ "signature_types": [
+ "System.Boolean",
+ "System.ServiceModel.Channels.RequestContext",
+ "System.ServiceModel.OperationContext"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.WcfIntegration",
+ "method": "HandleRequest",
+ "signature": "00 06 02 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "WebRequest",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System",
+ "type": "System.Net.WebRequest",
+ "method": "GetResponse",
+ "signature_types": [
+ "System.Net.WebResponse"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.WebRequestIntegration",
+ "method": "GetResponse",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Net.Requests",
+ "type": "System.Net.WebRequest",
+ "method": "GetResponse",
+ "signature_types": [
+ "System.Net.WebResponse"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.WebRequestIntegration",
+ "method": "GetResponse",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System",
+ "type": "System.Net.WebRequest",
+ "method": "GetResponseAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.WebRequestIntegration",
+ "method": "GetResponseAsync",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "System.Net.Requests",
+ "type": "System.Net.WebRequest",
+ "method": "GetResponseAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1"
+ ],
+ "minimum_major": 4,
+ "minimum_minor": 0,
+ "minimum_patch": 0,
+ "maximum_major": 4,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.WebRequestIntegration",
+ "method": "GetResponseAsync",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ },
+ {
+ "name": "XUnit",
+ "method_replacements": [
+ {
+ "caller": {},
+ "target": {
+ "assembly": "xunit.execution.dotnet",
+ "type": "Xunit.Sdk.TestInvoker`1",
+ "method": "RunAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 2,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.Testing.XUnitIntegration",
+ "method": "TestInvoker_RunAsync",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "xunit.execution.desktop",
+ "type": "Xunit.Sdk.TestInvoker`1",
+ "method": "RunAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 2,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.Testing.XUnitIntegration",
+ "method": "TestInvoker_RunAsync",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "xunit.execution.dotnet",
+ "type": "Xunit.Sdk.TestRunner`1",
+ "method": "RunAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 2,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.Testing.XUnitIntegration",
+ "method": "TestRunner_RunAsync",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "xunit.execution.desktop",
+ "type": "Xunit.Sdk.TestRunner`1",
+ "method": "RunAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 2,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.Testing.XUnitIntegration",
+ "method": "TestRunner_RunAsync",
+ "signature": "00 04 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "xunit.execution.dotnet",
+ "type": "Xunit.Sdk.TestAssemblyRunner`1",
+ "method": "RunTestCollectionAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "Xunit.Sdk.IMessageBus",
+ "Xunit.Abstractions.ITestCollection",
+ "System.Collections.Generic.IEnumerable`1",
+ "System.Threading.CancellationTokenSource"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 2,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.Testing.XUnitIntegration",
+ "method": "AssemblyRunner_RunAsync",
+ "signature": "00 08 1C 1C 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "xunit.execution.desktop",
+ "type": "Xunit.Sdk.TestAssemblyRunner`1",
+ "method": "RunTestCollectionAsync",
+ "signature_types": [
+ "System.Threading.Tasks.Task`1",
+ "Xunit.Sdk.IMessageBus",
+ "Xunit.Abstractions.ITestCollection",
+ "System.Collections.Generic.IEnumerable`1",
+ "System.Threading.CancellationTokenSource"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 2,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.Testing.XUnitIntegration",
+ "method": "AssemblyRunner_RunAsync",
+ "signature": "00 08 1C 1C 1C 1C 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "xunit.execution.dotnet",
+ "type": "Xunit.Sdk.TestOutputHelper",
+ "method": "QueueTestOutput",
+ "signature_types": [
+ "System.Void",
+ "System.String"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 2,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.Testing.XUnitIntegration",
+ "method": "TestOutputHelper_QueueTestOutput",
+ "signature": "00 05 01 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ },
+ {
+ "caller": {},
+ "target": {
+ "assembly": "xunit.execution.desktop",
+ "type": "Xunit.Sdk.TestOutputHelper",
+ "method": "QueueTestOutput",
+ "signature_types": [
+ "System.Void",
+ "System.String"
+ ],
+ "minimum_major": 2,
+ "minimum_minor": 2,
+ "minimum_patch": 0,
+ "maximum_major": 2,
+ "maximum_minor": 65535,
+ "maximum_patch": 65535
+ },
+ "wrapper": {
+ "assembly": "Datadog.Trace.ClrProfiler.Managed, Version=1.19.1.0, Culture=neutral, PublicKeyToken=def86d061d0d2eeb",
+ "type": "Datadog.Trace.ClrProfiler.Integrations.Testing.XUnitIntegration",
+ "method": "TestOutputHelper_QueueTestOutput",
+ "signature": "00 05 01 1C 1C 08 08 0A",
+ "action": "ReplaceTargetMethod"
+ }
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/lib/coreclr/src/inc/CMakeLists.txt b/lib/coreclr/src/inc/CMakeLists.txt
new file mode 100644
index 0000000000..c38d59587a
--- /dev/null
+++ b/lib/coreclr/src/inc/CMakeLists.txt
@@ -0,0 +1,90 @@
+set( CORGUIDS_IDL_SOURCES
+ cordebug.idl
+ xcordebug.idl
+ clrdata.idl
+ clrinternal.idl
+ xclrdata.idl
+ corprof.idl
+ corpub.idl
+ mscorsvc.idl
+ clrprivappxhosting.idl
+ clrprivbinding.idl
+ clrprivhosting.idl
+ clrprivruntimebinders.idl
+ corsym.idl
+ sospriv.idl
+)
+
+if(WIN32)
+#Build for corguids is done in two steps:
+#1. compile .idl to *_i.c : This is done using custom midl command
+#2. compile *_i.c to .lib
+
+# Get the current list of definitions to pass to midl
+get_compile_definitions(MIDL_DEFINITIONS)
+get_include_directories(MIDL_INCLUDE_DIRECTORIES)
+
+
+# Run custom midl command over each idl file
+FIND_PROGRAM( MIDL midl.exe )
+foreach(GENERATE_IDL IN LISTS CORGUIDS_IDL_SOURCES)
+ get_filename_component(IDLNAME ${GENERATE_IDL} NAME_WE)
+ set(OUT_NAME ${CMAKE_CURRENT_BINARY_DIR}/idls_out/${IDLNAME}_i.c)
+ list(APPEND CORGUIDS_SOURCES ${OUT_NAME})
+ add_custom_command(OUTPUT ${OUT_NAME}
+ COMMAND ${MIDL} ${MIDL_INCLUDE_DIRECTORIES} /h ${CMAKE_CURRENT_BINARY_DIR}/idls_out/${IDLNAME}.h ${MIDL_DEFINITIONS} /out ${CMAKE_CURRENT_BINARY_DIR}/idls_out ${CMAKE_CURRENT_SOURCE_DIR}/${GENERATE_IDL}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${GENERATE_IDL}
+ COMMENT "Compiling ${GENERATE_IDL}")
+endforeach(GENERATE_IDL)
+
+set_source_files_properties(${CORGUIDS_SOURCES}
+ PROPERTIES GENERATED TRUE)
+
+# Compile *_i.c as C files
+add_compile_options(/TC)
+
+else()
+
+#The MIDL tool exists for Windows only, so for other systems, we have the prebuilt xxx_i.cpp files checked in
+
+# The prebuilt files contain extra '!_MIDL_USE_GUIDDEF_' after the #endif, but not in the comment.
+# In order to not to have to modify these prebuilt files, we disable the extra tokens warning.
+if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+add_compile_options(-Wno-extra-tokens)
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+add_compile_options(-Wno-endif-labels)
+endif()
+
+add_compile_options(-D_MIDL_USE_GUIDDEF_)
+foreach(IDL_SOURCE IN LISTS CORGUIDS_IDL_SOURCES)
+ get_filename_component(IDLNAME ${IDL_SOURCE} NAME_WE)
+ set(C_SOURCE ../pal/prebuilt/idl/${IDLNAME}_i.cpp)
+ list(APPEND CORGUIDS_SOURCES ${C_SOURCE})
+endforeach(IDL_SOURCE)
+
+add_compile_options(-fPIC)
+endif(WIN32)
+
+if(FEATURE_JIT_PITCHING)
+ add_definitions(-DFEATURE_JIT_PITCHING)
+endif(FEATURE_JIT_PITCHING)
+
+# Compile *_i.cpp to lib
+_add_library(corguids ${CORGUIDS_SOURCES})
+
+# Binplace the inc files for packaging later.
+
+_install (FILES cfi.h
+ cor.h
+ cordebuginfo.h
+ coredistools.h
+ corhdr.h
+ corinfo.h
+ corjit.h
+ corjithost.h
+ opcode.def
+ openum.h
+ gcinfoencoder.h
+ gcinfotypes.h
+ DESTINATION inc)
+_install (TARGETS corguids DESTINATION lib)
diff --git a/lib/coreclr/src/inc/CrstTypeTool.cs b/lib/coreclr/src/inc/CrstTypeTool.cs
new file mode 100644
index 0000000000..0310ec3fb1
--- /dev/null
+++ b/lib/coreclr/src/inc/CrstTypeTool.cs
@@ -0,0 +1,994 @@
+// 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 tool exists to transform a high level description of Crst dependencies (i.e. which Crst type may be
+// acquired before or after other Crst types) into a header file that defines a enum to describe each Crst
+// type and tables that map type to numerical ranking and a string based name.
+//
+// To use the tool, run "csc.exe CrstTypeTool.cs" and run the resulting executable.
+//
+// The Crst type definition file is written in a very simple language. Comments begin with '//' and continue
+// to the end of the line. All remaining tokens after comment removal are simply sequences of non-whitespace
+// characters separated by whitespace. Keywords are case-insensitive and identifiers (which are always Crst
+// type names) are case sensitive. The language grammar is given below in EBNF-like form:
+//
+// TopLevel ::= CrstDefinition*
+//
+// CrstDefinition ::= 'Crst' CrstDependency* 'End'
+//
+// CrstDependency ::= 'AcquiredBefore' *
+// | 'AcquiredAfter' *
+// | 'SameLevelAs' *
+// | 'Unordered'
+//
+// Crst type names match the CrstType enums used in the source code minus the 'Crst' prefix. For example
+// CrstAppDomainCache is written as 'AppDomainCache' in the .def file.
+//
+// The dependency "A 'AcquiredBefore' B" indicates that CrstA may be legally held while CrstB is acquired.
+// Similarly "A 'AcquiredAfter' B" indicates that CrstA may be legally acquired while CrstB is held. "A
+// 'AcquiredBefore' B" is logically equivalent to "B 'AcquiredAfter' A" and authors may enter the dependency
+// is whichever seems to make the most sense to them (or add both rules if they so desire).
+//
+// 'Unordered' indicates that the Crst type does not participate in ranking (there should be very few Crsts
+// like this and those that are know how to avoid or deal with deadlocks manually).
+//
+// 'SameLevelAs' indicates the given Crst type may be acquired alongside any number of instances of the Crst
+// types indicated. "A 'SameLevel' B" automatically implies "B 'SameLevel' A" so it's not necessary to specify
+// the dependency both ways though authors can do so if they wish.
+//
+// Simple validation of the .def file (over and above syntax checking) is performed by this tool prior to
+// emitting the header file. This will catch logic errors such as referencing a Crst type that is not
+// defined or using the 'Unordered' attribute along with any other attribute within a single definition. It
+// will also catch cycles in the dependency graph (i.e. definitions that logically describe a system where the
+// Crst types can't be ranked).
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Text.RegularExpressions;
+
+// The main application class containing the program entry point.
+class CrstTypeTool
+{
+ // A hash containing every Crst type defined by the input .def file along with its attributes. Keyed by
+ // Crst type name (which is case sensitive and doesn't include the 'Crst' enum prefix).
+ Dictionary m_crsts = new Dictionary();
+
+ // The program entry point.
+ public static int Main()
+ {
+ try
+ {
+ // Calculate the filenames of the input and output files.
+ string inputFile = "CrstTypes.def";
+ string outputFile = "CrstTypes.h";
+
+ // A common error is to forget to check out the CrstTypes.h file first. Handle this case specially
+ // so we can give a good error message.
+ if (File.Exists(outputFile) && (File.GetAttributes(outputFile) & FileAttributes.ReadOnly) != 0)
+ {
+ Console.WriteLine(outputFile + " is read-only, you must check it out of TFS/SD first");
+ return 2;
+ }
+
+ // Create an instance of our application class to store state in (specifically the collection of
+ // Crst type definitions).
+ CrstTypeTool app = new CrstTypeTool();
+
+ // Create a parser for the CrstTypes.def file and run it over the input file (errors are signalled
+ // via exception, in common with all the following steps except validation).
+ new TypeFileParser().ParseFile(inputFile, app.m_crsts);
+
+ // Validate the collection of Crst type definitions we built up during parsing for common logic
+ // errors and the presence of dependency cycles. False is returned from ValidateCrsts if an error
+ // was detected (an error message will have already been output to the console at this point).
+ if (!app.ValidateCrsts())
+ return 3;
+
+ // Perform a topological sort to map each Crst type to a numeric ranking.
+ app.LevelCrsts();
+
+ // Emit the new header file containing Crst type definitions and ranking information.
+ app.WriteHeaderFile(outputFile);
+
+ // If we get here the transformation was successful; inform the user and we're done.
+ Console.WriteLine(outputFile + " successfully updated");
+ return 0;
+ }
+ catch (TypeFileParser.ParseError pe)
+ {
+ // Syntax errors specific to parsing the input file.
+ Console.WriteLine("ParseError: " + pe.Message);
+ return 4;
+ }
+ catch (Exception e)
+ {
+ // Any other general errors (file I/O problems, out of memory etc.).
+ Console.WriteLine("Unexpected exception:");
+ Console.WriteLine(e);
+ return 5;
+ }
+ }
+
+ // Emit the CrstTypes.h output file.
+ void WriteHeaderFile(string fileName)
+ {
+ FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
+ StreamWriter writer = new StreamWriter(stream);
+
+ // Create a collection based on all the Crst types we've stored in the hash. We do this so we can sort
+ // the Crst types we emit (lexically, based on type name).
+ Dictionary.ValueCollection crstCollection = m_crsts.Values;
+ CrstType[] crsts = new CrstType[crstCollection.Count];
+ crstCollection.CopyTo(crsts, 0);
+ Array.Sort(crsts);
+
+ // Emit the header. Contains copyright information, the usual goop to avoid multiple inclusion and a
+ // header comment to discourage direct editing and point the user at the CrstTypes.def file instead
+ // (where all will be explained in greater detail).
+ writer.WriteLine("//");
+ writer.WriteLine("// Licensed to the .NET Foundation under one or more agreements.");
+ writer.WriteLine("// The .NET Foundation licenses this file to you under the MIT license.");
+ writer.WriteLine("// See the LICENSE file in the project root for more information.");
+ writer.WriteLine("//");
+ writer.WriteLine();
+ writer.WriteLine("#ifndef __CRST_TYPES_INCLUDED");
+ writer.WriteLine("#define __CRST_TYPES_INCLUDED");
+ writer.WriteLine();
+ writer.WriteLine("// **** THIS IS AN AUTOMATICALLY GENERATED HEADER FILE -- DO NOT EDIT!!! ****");
+ writer.WriteLine();
+ writer.WriteLine("// This file describes the range of Crst types available and their mapping to a numeric level (used by the");
+ writer.WriteLine("// runtime in debug mode to validate we're deadlock free). To modify these settings edit the");
+ writer.WriteLine("// file:CrstTypes.def file and run the clr\\bin\\CrstTypeTool utility to generate a new version of this file.");
+ writer.WriteLine();
+
+ // Emit the CrstType enum to define a value for each crst type (along with the kNumberOfCrstTypes
+ // constant).
+ writer.WriteLine("// Each Crst type is declared as a value in the following CrstType enum.");
+ writer.WriteLine("enum CrstType");
+ writer.WriteLine("{");
+ for (int i = 0; i < crsts.Length; i++)
+ writer.WriteLine(" Crst" + crsts[i].Name + " = " + i.ToString() + ",");
+ writer.WriteLine(" kNumberOfCrstTypes = " + crsts.Length.ToString());
+ writer.WriteLine("};");
+ writer.WriteLine();
+
+ // This is the end of the regular part of the header included by most files.
+ writer.WriteLine("#endif // __CRST_TYPES_INCLUDED");
+ writer.WriteLine();
+
+ // There is a second section of the header intended for inclusion only by vm\Crst.cpp. This contains
+ // some data tables used to map crst type to rank or name. We could instead define two separate
+ // headers, but on the whole it seems simpler to do it this way.
+ writer.WriteLine("// Define some debug data in one module only -- vm\\crst.cpp.");
+ writer.WriteLine("#if defined(__IN_CRST_CPP) && defined(_DEBUG)");
+ writer.WriteLine();
+
+ // Emit the crst type to rank mapping table.
+ writer.WriteLine("// An array mapping CrstType to level.");
+ writer.WriteLine("int g_rgCrstLevelMap[] =");
+ writer.WriteLine("{");
+ foreach (CrstType crst in crsts)
+ {
+ string crstLine = " " + crst.Level + ",";
+ crstLine = crstLine + new string(' ', 16 - crstLine.Length);
+ writer.WriteLine(crstLine + "// Crst" + crst.Name);
+ }
+ writer.WriteLine("};");
+ writer.WriteLine();
+
+ // Emit the crst type to name mapping table.
+ writer.WriteLine("// An array mapping CrstType to a stringized name.");
+ writer.WriteLine("LPCSTR g_rgCrstNameMap[] =");
+ writer.WriteLine("{");
+ foreach (CrstType crst in crsts)
+ writer.WriteLine(" \"Crst" + crst.Name + "\",");
+ writer.WriteLine("};");
+ writer.WriteLine();
+
+ // Emit the constant Crst.cpp uses to record an unordered rank.
+ writer.WriteLine("// Define a special level constant for unordered locks.");
+ writer.WriteLine("#define CRSTUNORDERED (-1)");
+ writer.WriteLine();
+
+ // Emit a couple of inline helpers to map type to rank or name (and validate the type while they're at
+ // it).
+ writer.WriteLine("// Define inline helpers to map Crst types to names and levels.");
+ writer.WriteLine("inline static int GetCrstLevel(CrstType crstType)");
+ writer.WriteLine("{");
+ writer.WriteLine(" LIMITED_METHOD_CONTRACT;");
+ writer.WriteLine(" _ASSERTE(crstType >= 0 && crstType < kNumberOfCrstTypes);");
+ writer.WriteLine(" return g_rgCrstLevelMap[crstType];");
+ writer.WriteLine("}");
+ writer.WriteLine("inline static LPCSTR GetCrstName(CrstType crstType)");
+ writer.WriteLine("{");
+ writer.WriteLine(" LIMITED_METHOD_CONTRACT;");
+ writer.WriteLine(" _ASSERTE(crstType >= 0 && crstType < kNumberOfCrstTypes);");
+ writer.WriteLine(" return g_rgCrstNameMap[crstType];");
+ writer.WriteLine("}");
+ writer.WriteLine();
+
+ // And that's the end of the second section of the header file.
+ writer.WriteLine("#endif // defined(__IN_CRST_CPP) && defined(_DEBUG)");
+
+ writer.Close();
+ stream.Close();
+ }
+
+ // Peform checking of the Crst type definitions we've read just read. Various forms of logic error are
+ // scanned for including cycles in the dependency graph. Returns true if no errors are found. If false is
+ // returned a descriptive error message will have already been written to the console.
+ bool ValidateCrsts()
+ {
+ // Look at each Crst type definition in turn.
+ foreach (CrstType crst in m_crsts.Values)
+ {
+ // Catch Crst types that are referenced but never defined.
+ if (!crst.Defined)
+ {
+ Console.WriteLine(String.Format("Error: CrstType 'Crst{0}' is referenced without being defined",
+ crst.Name));
+ return false;
+ }
+
+ // Catch the use of the 'Unordered' attribute alongside the 'AcquiredBefore' attribute (which
+ // indicates an ordering).
+ if (crst.Level == CrstType.CrstUnordered && (crst.AcquiredBeforeList.Count > 0 ||
+ crst.Group != null))
+ {
+ Console.WriteLine(String.Format("Error: CrstType 'Crst{0}' is declared as both unordered and acquired before 'Crst{1}'",
+ crst.Name, crst.AcquiredBeforeList[0].Name));
+ return false;
+ }
+
+ // Catch the use of the 'Unordered' attribute alongside the 'SameLevelAs' attribute (which
+ // indicates an ordering).
+ if (crst.Level == CrstType.CrstUnordered && crst.Group != null)
+ {
+ Console.WriteLine(String.Format("Error: CrstType 'Crst{0}' is declared as both unordered and in the same level as another CrstType",
+ crst.Name));
+ return false;
+ }
+
+ // Catch the simple cycle where the Crst type depends on itself.
+ if (crst.AcquiredBeforeList.Contains(crst))
+ {
+ Console.WriteLine(String.Format("Error: CrstType 'Crst{0}' is declared as being acquired before itself",
+ crst.Name));
+ return false;
+ }
+
+ // Look for deeper cycles using a recursive algorithm in 'FindCycle()'.
+ List cycleList = new List();
+ if (FindCycle(crst, crst, cycleList))
+ {
+ Console.WriteLine(String.Format("Error: CrstType 'Crst{0}' is involved in a dependency cycle with the following CrstTypes:",
+ crst.Name));
+ foreach (CrstType cycleCrst in cycleList)
+ Console.WriteLine(String.Format(" Crst{0}", cycleCrst.Name));
+ return false;
+ }
+ }
+
+ // Perform normalization of each set of Crst types that are included in the same group (i.e. have a
+ // 'SameLevelAs' relationship). Normalization means that each Crst type in a group will have exactly
+ // the same set of dependency rules as all the others.
+ CrstTypeGroup.NormalizeAllRules();
+
+ // The normalization process could have introduced cycles in the dependency graph so run the cycle
+ // detection pass again. We do separate passes like this since normalizing can lead to less intuitive
+ // error messages if a cycle is found: so if the cycle exists before normalization takes place we want
+ // to generate an error message then.
+ foreach (CrstType crst in m_crsts.Values)
+ {
+ List cycleList = new List();
+ if (FindCycle(crst, crst, cycleList))
+ {
+ Console.WriteLine(String.Format("Error: CrstType 'Crst{0}' is involved in a dependency cycle with the following CrstTypes:",
+ crst.Name));
+ foreach (CrstType cycleCrst in cycleList)
+ Console.WriteLine(String.Format(" Crst{0}", cycleCrst));
+ Console.WriteLine("Note that the cycle was detected only after 'SameLevelAs' processing was performed so some CrstType dependencies are implied by peer CrstTypes");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // Recursively determine if a cycle exists in the Crst type dependency graph rooted at the 'rootCrst'
+ // type. The 'currCrst' indicates the next dependency to be examined (it will be the same as the
+ // 'rootCrst' when we're first called). The 'cycleList' argument contains a list of Crst types we've
+ // already examined in this branch of the algorithm and serves both to avoid checking the same node twice
+ // and to provide a list of the involved Crst types should a cycle be detected.
+ // Note that this algorithm is not designed to detect general cycles in the graph, only those that involve
+ // the 'rootCrst' directly. This is somewhat inefficient but gives us a simple way to generate clear error
+ // messages.
+ bool FindCycle(CrstType rootCrst, CrstType currCrst, List cycleList)
+ {
+ // Add the current Crst type to the list of those we've seen.
+ cycleList.Add(currCrst);
+
+ // Look through all the dependencies of the current Crst type.
+ foreach (CrstType childCrst in currCrst.AcquiredBeforeList)
+ {
+ // If we find a reference back to the root Crst type then we've found a cycle. Start backing out
+ // from the recursion (keeping the list of nodes we visited intact) by returning true.
+ if (childCrst == rootCrst)
+ return true;
+
+ // Otherwise iterate over the dependencies of the current node and for each one that we haven't
+ // already seen and recursively extend the search.
+ if (!cycleList.Contains(childCrst))
+ if (FindCycle(rootCrst, childCrst, cycleList))
+ return true;
+ }
+
+ // Didn't find any cycles involving the root and this node; remove this node from the potential cycle
+ // list and return up to our caller indicating such.
+ cycleList.RemoveAt(cycleList.Count - 1);
+
+ return false;
+ }
+
+ // Topologically sort all the Crsts so we can assign a total ordering to them (in the form of a numeric
+ // ranking). Ranks start from 0 (Crst types that may be acquired at any time) and increment from there
+ // (Crst types that may only be acquired if a lower type is not already held).
+ // **** NOTE: The leveling process is destructive in that we will lose all dependency information from the
+ // Crst type definitions during the course of the algorithm.
+ void LevelCrsts()
+ {
+ // Note that Crst type dependency rules have been normalized (by the input parser) so that all
+ // AcquiredBefore/AcquiredAfter relationships have been reduced to AcquiredBefore relationships (i.e.
+ // any rule of the form "A AcquiredAfter B" has been converted to "B AcquiredBefore A". Any
+ // normalization makes the algorithm easier to program, but a normaliztion to AcquiredBefore
+ // relationships was chosen since it makes it particularly easy to implement an algorithm that assigns
+ // ranks beginning with zero and moving up to an arbitrary level. Any type that doesn't have any
+ // AcquiredBefore dependencies can always be ranked at a lower level than any remaining unranked types
+ // by definition and from this we can derive a simple iterative process to rank all the crst types.
+
+ // Calculate how many Crst types we have left to rank (some are not included in this step because
+ // they've been marked as 'Unordered' in the input file).
+ int unsorted = 0;
+ foreach (CrstType crst in m_crsts.Values)
+ if (crst.Level == CrstType.CrstUnassigned)
+ unsorted++;
+
+ // The ranking level we're going to assign to Crst types on the next pass of the algorithm.
+ int currLevel = 0;
+
+ // Iterate while we still have Crst types left to rank. On each pass we'll assign a rank to those
+ // types that no longer have any dependencies forcing them to have a higher rank and then remove
+ // dependency rules involving those newly ranked types from the remaining types.
+ while (unsorted > 0)
+ {
+ // Record a flag indicating whether we manage to assign a rank to at least one Crst type on this
+ // pass. If we ever fail to do this we've hit a cycle (this is just paranoia, the Crst declaration
+ // validation performed in ValidateCrsts() should have detected such a cycle first).
+ bool madeProgress = false;
+
+ // If we spot any types that are in a group (SameLevelAs relationship) then we defer assigning a
+ // rank till we've dealt with any non-group types (we wish to always place type groups in their
+ // very own rank else the Crst rank violation detection code won't detect violations between
+ // members of the group and singleton types that happened to be assigned rank on the same pass).
+ List deferredGroups = new List();
+
+ // Scan through all the Crst types.
+ foreach (CrstType crst in m_crsts.Values)
+ {
+ // Skip those types that already have a rank assigned.
+ if (crst.Level != CrstType.CrstUnassigned)
+ continue;
+
+ // We're looking for Crst types that no longer have any types that can be acquired while they
+ // are already held. This indicates that it's safe to assign the current rank to them (since
+ // there are no remaining dependencies that need to be ranked first (i.e. with a lower rank
+ // value than this type).
+ if (crst.AcquiredBeforeList.Count == 0)
+ {
+ if (crst.Group == null)
+ {
+ // If this type is not part of the group we can go and assign the rank right away.
+ crst.Level = currLevel;
+ madeProgress = true;
+ unsorted--;
+ }
+ else if (!deferredGroups.Contains(crst.Group))
+ // Otherwise we'll defer ranking this group member until all the singletons are
+ // processed.
+ deferredGroups.Add(crst.Group);
+ }
+ }
+
+ // We've gone through the entire collection of Crst types and assigned the current rank level to
+ // any singleton Crst types that qualify. Now deal with any group members we detected (it's
+ // possible that more than one group qualifies for ranking at this level but we need to be careful
+ // to assign distinct rank values to each group to avoid hiding lock rank violations (since group
+ // members are always allowed to be acquired alongside any other type with the same rank value).
+ // Iterate over each distinct group that we found in this pass.
+ foreach (CrstTypeGroup group in deferredGroups)
+ {
+ // Look at our progress flag here. If it is false then we didn't have any singleton Crst types
+ // ranked at this level and we haven't processed any other groups at this level either. Thus
+ // we can rank this group at the current level. Otherwise at least one type was already ranked
+ // with this level so we need to increment to a new, distinct level to avoid ranking
+ // ambiguity.
+ if (madeProgress)
+ currLevel++;
+
+ // Iterate through each Crst type that is a member of this group assigning them the (same)
+ // current rank.
+ foreach (CrstType crst in group.Members)
+ {
+ // Double check that each member has the same dependencies (i.e. they should all be empty
+ // by now). There should be no way that this error should ever occur, it's just paranoia
+ // on my part.
+ if (crst.AcquiredBeforeList.Count != 0)
+ throw new Exception("Internal error: SameLevel CrstTypes with differing rulesets");
+
+ crst.Level = currLevel;
+ unsorted--;
+ }
+
+ // Once we've processed at least one group we've made progress this iteration.
+ madeProgress = true;
+ }
+
+ // If we didn't manage to assign rank to at least one Crst type then we're not going to do any
+ // better next iteration either (because no state was updated in this iteration). This should only
+ // occur in the presence of a dependency cycle and we shouldn't get that here after a successful
+ // call to ValidateCrsts(), so this check is pure paranoia.
+ if (!madeProgress)
+ {
+ Console.WriteLine(String.Format("{0} unsorted remain", unsorted));
+ throw new Exception("Cycle detected trying to assign level " + currLevel.ToString());
+ }
+
+ // Loop through all the unranked Crsts types and remove any AcquiredBefore relationships that
+ // involve types we've already leveled (since those types, by definition, have already been
+ // assigned a lower rank).
+ foreach (CrstType crst in m_crsts.Values)
+ {
+ if (crst.Level != CrstType.CrstUnassigned)
+ continue;
+ List prunedCrsts = crst.AcquiredBeforeList.FindAll(Unleveled);
+ crst.AcquiredBeforeList = prunedCrsts;
+ }
+
+ // Done with this rank level, move to the next.
+ currLevel++;
+ }
+ }
+
+ // Predicate method used with List.FindAll() to locate Crst types that haven't had their rank assigned
+ // yet.
+ static bool Unleveled(CrstType crst)
+ {
+ return crst.Level == CrstType.CrstUnassigned;
+ }
+}
+
+// Class used to parse a CrstTypes.def file into a dictionary of Crst type definitions. It uses a simple lexer
+// that removes comments then forms tokens out of any consecutive non-whitespace characters. An equally simple
+// recursive descent parser forms Crst instances by parsing the token stream.
+class TypeFileParser
+{
+ // Remember the input file name and the dictionary we're meant to populate.
+ string m_typeFileName;
+ Dictionary m_crsts;
+
+ // Compile regular expressions for detecting comments and tokens in the parser input.
+ Regex m_commentRegex = new Regex(@"//.*");
+ Regex m_tokenRegex = new Regex(@"^(\s*(\S+)\s*)*");
+
+ // Input is lexed into an array of tokens. We record the index of the token being currently parsed.
+ Token[] m_tokens;
+ int m_currToken;
+
+ // Parse the given file into Crst type definitions and place these definitions in the dictionary provided.
+ // Syntax errors are signalled via ParseError derived exceptions.
+ public void ParseFile(string typeFileName, Dictionary crsts)
+ {
+ m_typeFileName = typeFileName;
+ m_crsts = crsts;
+
+ // Lex the file into tokens.
+ InitTokenStream();
+
+ // Parse the tokens according to the grammar set out at the top of this file.
+ // Loop until we have no further tokens to process.
+ while (!IsEof())
+ {
+ // Grab the next token.
+ Token token = NextToken();
+
+ // We're at the top level, so the token had better be 'Crst'.
+ if (token.Id != KeywordId.Crst)
+ throw new UnexpectedTokenError(token, KeywordId.Crst);
+
+ // OK, parse the rest of this single Crst type definition.
+ ParseCrst();
+ }
+ }
+
+ // Parse a single Crst type definition.
+ void ParseCrst()
+ {
+ // The next token had better be an identifier (the Crst type name).
+ Token token = NextToken();
+ if (token.Id != KeywordId.Id)
+ throw new UnexpectedTokenError(token, KeywordId.Id);
+
+ // The Crst instance might already exist in the dictionary (forward references to a Crst type cause
+ // these entries to auto-vivify). But in that case the entry better not be marked as 'Defined' which
+ // would indicate a double declaration.
+ CrstType crst;
+ if (m_crsts.ContainsKey(token.Text))
+ {
+ crst = m_crsts[token.Text];
+ if (crst.Defined)
+ throw new ParseError(String.Format("Duplicate definition for CrstType '{0}'", token.Text), token);
+ }
+ else
+ {
+ // Otherwise this Crst type hasn't been seen thus far so we allocate a new instance and add it to
+ // the dictionary.
+ crst = new CrstType(token.Text);
+ m_crsts.Add(crst.Name, crst);
+ }
+
+ // We're defining, not just referencing this type.
+ crst.Defined = true;
+
+ // Parse any attributes inside this definition (until we see an 'End' token).
+ bool parsingCrst = true;
+ while (parsingCrst)
+ {
+ // Get the next token. Either some attribute keyword or 'End'.
+ token = NextToken();
+ List list;
+
+ switch (token.Id)
+ {
+
+ case KeywordId.AcquiredBefore:
+ // Simply parse the following list of Crst types into the current type's AcquiredBefore list.
+ ParseList(crst.AcquiredBeforeList);
+ break;
+
+ case KeywordId.AcquiredAfter:
+ // AcquiredAfter is trickier. To make the ranking algorithm's life easier we actually
+ // normalize all rules to the AcquiredBefore form (see LevelCrsts() for the reasoning). So we
+ // capture the list of Crst types that follow the AcquiredAfter keyword and then append the
+ // current type to the AcquiredBefore list of each type found.
+ list = new List();
+ ParseList(list);
+ foreach (CrstType priorCrst in list)
+ priorCrst.AcquiredBeforeList.Add(crst);
+ break;
+
+ case KeywordId.SameLevelAs:
+ // Parse the following list of Crst types them let the CrstTypeGroup class handle the
+ // resulting updates to the type groups we're currently maintaining. See the comments for the
+ // CrstTypeGroup class for more details.
+ list = new List();
+ ParseList(list);
+ foreach (CrstType sameLevelCrst in list)
+ CrstTypeGroup.Join(crst, sameLevelCrst);
+ break;
+
+ case KeywordId.Unordered:
+ crst.Level = CrstType.CrstUnordered;
+ break;
+
+ case KeywordId.End:
+ parsingCrst = false;
+ break;
+
+ default:
+ throw new UnexpectedTokenError(token,
+ KeywordId.AcquiredBefore,
+ KeywordId.AcquiredAfter,
+ KeywordId.SameLevelAs,
+ KeywordId.Unordered);
+ }
+ }
+ }
+
+ // Parse a list of Crst type names. Any other token terminates the list (without error and without
+ // consuming that token from the stream). The list of tokens is returned as a list of corresponding
+ // CrstTypes (which are auto-vivified in the output dictionary if they haven't been declared yet).
+ void ParseList(List list)
+ {
+ // Parse tokens until we find a non-indentifier.
+ while (true)
+ {
+ Token token = NextToken();
+ if (token.Id != KeywordId.Id)
+ {
+ // We found the list terminator. Push the non-identifier token back into the stream for our
+ // caller to parse correctly.
+ UnwindToken();
+ return;
+ }
+
+ // Look up or add a new CrstType corresponding to this type name.
+ CrstType crst;
+ if (m_crsts.ContainsKey(token.Text))
+ crst = m_crsts[token.Text];
+ else
+ {
+ crst = new CrstType(token.Text);
+ m_crsts[crst.Name] = crst;
+ }
+
+ // Add the type to the output list we're building.
+ list.Add(crst);
+ }
+ }
+
+ // Lex the input file into an array of tokens.
+ void InitTokenStream()
+ {
+ StreamReader file = new StreamReader(m_typeFileName);
+ int lineNumber = 1;
+ List tokenList = new List();
+
+ // Read the file a line at a time.
+ string line;
+ while ((line = file.ReadLine()) != null)
+ {
+ // Remove comments from the current line.
+ line = m_commentRegex.Replace(line, "");
+
+ // Match all contiguous non-whitespace characters as individual tokens.
+ Match match = m_tokenRegex.Match(line);
+ if (match.Success)
+ {
+ // For each token captured build a token instance and record the token text and the file, line
+ // and column at which it was encountered (these latter in order to produce useful syntax
+ // error messages).
+ CaptureCollection cap = match.Groups[2].Captures;
+ for (int i = 0; i < cap.Count; i++)
+ tokenList.Add(new Token(m_typeFileName, cap[i].Value, lineNumber, cap[i].Index));
+ }
+
+ lineNumber++;
+ }
+
+ // Record the list of tokens we captured as an array and reset the index of the next token to be
+ // handled by the parser.
+ m_tokens = tokenList.ToArray();
+ m_currToken = 0;
+ }
+
+ // Have we run out of tokens to parse?
+ bool IsEof()
+ {
+ return m_currToken >= m_tokens.Length;
+ }
+
+ // Get the next token and throw an exception if we ran out.
+ Token NextToken()
+ {
+ if (m_currToken >= m_tokens.Length)
+ throw new UnexpectedEofError();
+ return m_tokens[m_currToken++];
+ }
+
+ // Push the last token parsed back into the stream.
+ void UnwindToken()
+ {
+ if (m_currToken <= 0)
+ throw new InvalidOperationException();
+ m_currToken--;
+ }
+
+ // The various keywords we can encounter (plus Id for identifiers, which are currently always Crst type
+ // names).
+ internal enum KeywordId
+ {
+ Id,
+ Crst,
+ End,
+ AcquiredBefore,
+ AcquiredAfter,
+ Unordered,
+ SameLevelAs,
+ }
+
+ // Class encapsulating a single token captured from the input file.
+ internal class Token
+ {
+ // Hash of keyword text to enum values.
+ static Dictionary s_keywords;
+
+ // The characters comprising the text of the token from the input file.
+ string m_text;
+
+ // Where the token was found (for error messages).
+ string m_file;
+ int m_line;
+ int m_column;
+
+ // The ID of the keyword this token represents (or KeywordId.Id).
+ KeywordId m_id;
+
+ // Static class initialization.
+ static Token()
+ {
+ // Populate the keyword hash. No sense building complex finite state machines to improve the
+ // efficiency of keyword lexing here since the input file (and keyword set) is never going to be
+ // big enough to justify the extra work.
+ s_keywords = new Dictionary();
+ s_keywords.Add("crst", KeywordId.Crst);
+ s_keywords.Add("end", KeywordId.End);
+ s_keywords.Add("acquiredbefore", KeywordId.AcquiredBefore);
+ s_keywords.Add("acquiredafter", KeywordId.AcquiredAfter);
+ s_keywords.Add("unordered", KeywordId.Unordered);
+ s_keywords.Add("samelevelas", KeywordId.SameLevelAs);
+ }
+
+ public Token(string file, string text, int line, int column)
+ {
+ m_file = file;
+ m_text = text;
+ m_line = line;
+ m_column = column;
+
+ // Map token text to keyword ID. True keywords (not identifiers) are case insensitive so normalize
+ // the text to lower case before performing the keyword hash lookup.
+ string canonName = m_text.ToLower();
+ if (s_keywords.ContainsKey(canonName))
+ m_id = s_keywords[canonName];
+ else
+ m_id = KeywordId.Id;
+ }
+
+ public string Text {get { return m_text; }}
+ public string Location {get { return String.Format("{0} line {1}, column {2}", m_file, m_line, m_column); }}
+ public KeywordId Id {get { return m_id; }}
+ }
+
+ // Base class for all syntax errors reported by the parser.
+ internal class ParseError : Exception
+ {
+ // A raw error message.
+ public ParseError(string message)
+ : base(message)
+ {}
+
+ // An error message tagged with a file, line and column (coming from an error token).
+ public ParseError(string message, Token errorToken)
+ : base(String.Format("{0}: {1}", errorToken.Location, message))
+ {}
+
+ // Produce a textual name for the given keyword type.
+ protected static string IdToName(KeywordId id)
+ {
+ if (id == KeywordId.Id)
+ return "a CrstType name";
+ return String.Format("'{0}'", id.ToString());
+ }
+ }
+
+ // Syntax error used when an unexpected token is encountered which further lists the valid tokens that
+ // would otherwise have been accepted.
+ internal class UnexpectedTokenError : ParseError
+ {
+ // Produce an unexpected token message with a file, line and column coming from an error token and
+ // optionally the names of zero or more tokens that would have been accepted.
+ public UnexpectedTokenError(Token errorToken, params KeywordId[] expected)
+ : base(FormatErrorMessage(errorToken, expected))
+ {}
+
+ static string FormatErrorMessage(Token errorToken, KeywordId[] expected)
+ {
+ StringBuilder message = new StringBuilder(String.Format("Unexpected token '{0}' at {1}",
+ errorToken.Text, errorToken.Location));
+ if (expected.Length == 0)
+ {
+ }
+ else if (expected.Length == 1)
+ {
+ message.Append(String.Format("; expected {0}", IdToName(expected[0])));
+ }
+ else
+ {
+ message.Append("; expected one of ");
+ for (int i = 0; i < expected.Length - 1; i++)
+ message.Append(String.Format("{0}, ", IdToName(expected[i])));
+ message.Append(IdToName(expected[expected.Length - 1]));
+
+ }
+
+ return message.ToString();
+ }
+ }
+
+ // Syntax error used when we unexpectedly ran out of tokens.
+ internal class UnexpectedEofError : ParseError
+ {
+ public UnexpectedEofError()
+ : base("Unexpected end of file")
+ {}
+ }
+}
+
+// This class represents an instance of a Crst type. These are unqiuely identified by case-sensitive name (the
+// same as the enum name used in vm code, minus the 'Crst' prefix).
+class CrstType : IComparable
+{
+ // Special level constants used to indicate unordered Crst types or those types we haven't gotten around
+ // to ranking yet.
+ public static readonly int CrstUnordered = -1;
+ public static readonly int CrstUnassigned = -2;
+
+ // Name of the type, e.g. "AppDomainCache" for the CrstAppDomainCache type.
+ string m_name;
+
+ // The numeric ranking assigned to this type. Starts as CrstUnassigned and then becomes either
+ // CrstUnordered (while parsing the input file) or a number >= 0 (during LevelCrsts()).
+ int m_level;
+
+ // List of Crst types that can be legally acquired while this one is held. (AcquiredAfter relationships
+ // are by switching the terms and adding to the second type's AcquiredBefore list).
+ List m_acquiredBeforeCrsts;
+
+ // Either null if this Crst type is not in (or has not yet been determined to be in) a SameLevelAs
+ // relationship or points to a CrstTypeGroup that records all the sibling types at the same level (that
+ // have been discovered thus far during parsing).
+ CrstTypeGroup m_group;
+
+ // Set once a definition for this type has been discovered. Used to detect double definitions and types
+ // referenced without definitions.
+ bool m_defined;
+
+ public CrstType(string name)
+ {
+ m_name = name;
+ m_level = CrstUnassigned;
+ m_acquiredBeforeCrsts = new List();
+ m_group = null;
+ m_defined = false;
+ }
+
+ public string Name {get { return m_name; }}
+ public int Level {get { return m_level; } set { m_level = value; }}
+ public List AcquiredBeforeList {get { return m_acquiredBeforeCrsts; } set { m_acquiredBeforeCrsts = value; }}
+ public CrstTypeGroup Group {get { return m_group; } set { m_group = value; }}
+ public bool Defined {get {return m_defined; } set { m_defined = value; }}
+
+ // Helper used to sort CrstTypes. The sort order is lexical based on the type name.
+ public int CompareTo(object other)
+ {
+ return m_name.CompareTo(((CrstType)other).m_name);
+ }
+}
+
+// Every time a SameLevelAs relationship is used we need to be careful to keep track of the transitive closure
+// of all types bound in the relationship. That's because such a relationship impacts the other dependency
+// rules (each member of a SameLevelAs group must behave as though it has exactly the same dependency rules as
+// all the others). Identifying all the members is tricky because "A SameLevelAs B" and "B SameLevelAs C"
+// implies "A SameLevelAs C". So we use a separate tracking structure, instances of the CrstTypeGroup type, to
+// do the bookkeeping for us. Each Crst type belongs to either zero or one CrstTypeGroups. As we find new
+// SameLevelAs relationships we create new groups, add types to existing groups or merge groups (as previous
+// distinct groups are merged by the discovery of a SameLevelAs relationship that links them). By the time
+// parsing has finished we are guaranteed to have discovered all the distinct, disjoint groups and to have
+// fully populated them with the transitive closure of all related types. We can them normalize all groups
+// members so they share the same AcquiredBefore relationships.
+class CrstTypeGroup
+{
+ // We record every group that has been formed so far. This makes normalizing all groups easier.
+ static List s_groups = new List();
+
+ // Crst types that are members of the current group. There are no duplicates in this list.
+ List m_members = new List();
+
+ // Declare a SameLevelAs relationship between the two Crst types given. Groups will be assigned, created
+ // or merged as required to maintain our guarantees (each CrstType is a member of at most one group and
+ // all CrstTypes involved in the same transitive closure of a SameLevelAs relationship are members of one
+ // group).
+ public static void Join(CrstType crst1, CrstType crst2)
+ {
+ CrstTypeGroup group;
+
+ if (crst1 == crst2)
+ {
+ // In this case the type refers to itself. Create a singleton group for this type if it doesn't
+ // already exist.
+ if (crst1.Group == null)
+ {
+ group = new CrstTypeGroup();
+ group.m_members.Add(crst1);
+
+ s_groups.Add(group);
+
+ crst1.Group = group;
+ }
+ }
+ else if (crst1.Group == null && crst2.Group == null)
+ {
+ // Neither types belong to a group already. So we can create a new one and add both types to it.
+ group = new CrstTypeGroup();
+ group.m_members.Add(crst1);
+ group.m_members.Add(crst2);
+
+ s_groups.Add(group);
+
+ crst1.Group = group;
+ crst2.Group = group;
+ }
+ else if (crst1.Group == null)
+ {
+ // The first type doesn't belong to a group yet but the second does. So we can simply add the
+ // first type to the second group.
+ group = crst2.Group;
+ group.m_members.Add(crst1);
+
+ crst1.Group = group;
+ }
+ else if (crst2.Group == null)
+ {
+ // As for the case above but the group/no-group positions are reversed.
+ group = crst1.Group;
+ group.m_members.Add(crst2);
+
+ crst2.Group = group;
+ }
+ else if (crst1.Group != crst2.Group)
+ {
+ // Both types belong to different groups so we'll have to merge them. Add the members of group 2
+ // to group 1 and throw away group 2.
+ group = crst1.Group;
+ CrstTypeGroup absorbGroup = crst2.Group;
+ foreach (CrstType crst in absorbGroup.m_members)
+ {
+ group.m_members.Add(crst);
+ crst.Group = group;
+ }
+
+ s_groups.Remove(absorbGroup);
+ }
+
+ // The only case left is when both types are already in the same group and there's no work needed in
+ // this case.
+ }
+
+ // Normalize all the groups we created during parsing. See below for the definition of normalization.
+ public static void NormalizeAllRules()
+ {
+ foreach (CrstTypeGroup group in s_groups)
+ group.NormalizeRules();
+ }
+
+ // Normalize this group. This involves adjusting the AcquiredBefore list of each member to be the union of
+ // all such rules within the group. This step allows us to detect cycles in the dependency graph that
+ // would otherwise remain hidden if we only examined the unnormalized AcquiredBefore rules.
+ void NormalizeRules()
+ {
+ // This local will contain the union of all AcquiredBefore rules.
+ List acquiredBeforeList = new List();
+
+ // Iterate through each member of the group.
+ foreach (CrstType crst in m_members)
+ {
+ // Add each AcquiredBefore rule we haven't already seen to the union.
+ foreach (CrstType afterCrst in crst.AcquiredBeforeList)
+ if (!acquiredBeforeList.Contains(afterCrst))
+ acquiredBeforeList.Add(afterCrst);
+ }
+
+ // Reset each member's AcquiredBefore list to a copy of the union we calculated. Note it's important
+ // to make a (shallow) copy because the ranking process modifies this list and so a shared copy would
+ // cause unexpected results.
+ foreach (CrstType crst in m_members)
+ crst.AcquiredBeforeList = acquiredBeforeList.GetRange(0, acquiredBeforeList.Count);
+ }
+
+ public List Members {get { return m_members; }}
+}
diff --git a/lib/coreclr/src/inc/CrstTypes.def b/lib/coreclr/src/inc/CrstTypes.def
new file mode 100644
index 0000000000..4dce8f243a
--- /dev/null
+++ b/lib/coreclr/src/inc/CrstTypes.def
@@ -0,0 +1,711 @@
+// 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 file is used to describe the different types of Crst and their dependencies on other Crst types (in
+// terms of which types may be legally held while others are acquired).
+//
+// The CrstTypeTool utility is used to parse this file, verify that there are no logical inconsistencies (such
+// as a cycle in the dependencies) and generate an enum value and numerical ranking for each type. This
+// ranking is used by the runtime (in checked builds) to verify that none of the rules described below are
+// violated (which could lead to a deadlock).
+//
+// When you add a new Crst type you need to be aware of which Crst types may be already held when your Crst is
+// acquired and which other types may be subsequently acquired. You can then add a Crst definition to this
+// file and annotate it with those dependencies. Running CrstTypeTool will check to see if this introduces a
+// potential deadlock problem and if everything checks out will generate a new version of
+// file:CrstTypes.h (be sure to check this file out from TFS/SD before running CrstTypeTool).
+//
+// The format of this file is a very simple language. Comments are introduced with '//' and continue to the
+// end of the line. Keywords are case insensitive (Crst type names, however, are case sensitive since they'll
+// be translated directly to C++ enum values). Crst type names are used without the 'Crst' prefix used in C++
+// code (e.g. CrstAppDomainCache is referred to as AppDomainCache). The following words are reserved keywords
+// and may not be used as the names of Crst types:
+// Crst
+// End
+// AcquiredBefore
+// AcquiredAfter
+// Unordered
+// SameLevelAs
+//
+// Each Crst type definition has the following format (where [] indicates optional and ... indicates zero or
+// more repetitions):
+// Crst
+// [AcquiredBefore ...]
+// [AcquiredAfter ...]
+// [SameLevelAs ...]
+// [Unordered]
+// End
+//
+// For example:
+// Crst Foo
+// AcquiredBefore Bar
+// AcquiredAfter Zob Baz
+// SameLevelAs Foo
+// End
+//
+// This introduces a new Crst type Foo (CrstFoo inside the runtime). This type may be legally acquired when
+// the current thread holds Crst instances of type Zob, Bar or even other instances of Foo. While Foo is held
+// it is legal to acquire Crsts of type Bar. Assuming that this definition does not introduce any dependency
+// cycles, CrstTypeTool will assign a numeric rank to CrstFoo that maximizes the chance that any other Crst
+// type interaction you didn't explicitly specify (e.g. holding Foo while taking a Crst of type Wibble) will
+// generate a ranking violation assert in the checked build.
+//
+// Note that the following set of definitions:
+// Crst A AcquiredBefore B End
+// Crst B End
+//
+// Crst A End
+// Crst B AcquiredAfter A End
+//
+// Crst A AcquiredBefore B End
+// Crst B AcquiredAfter A End
+//
+// are all equivalent. You are free to use whichever variant seems clearest to you (CrstTypeTool will tell you
+// if you introduce conflicting rules). Similarly "A SameLevelAs B" implies "B SameLevelAs A". The initial
+// contents of this file uses AcquiredBefore in preference to AcquiredAfter purely because it was generated
+// automatically by a profiling mechanism (the initial rules were seeded from observations of Crst usage while
+// running our test suites). Feel free to add meaningful comments to existing rules if you feel they can
+// usefully clarify the reasons for particular dependencies.
+//
+// See CrstTypeTool.cs for how to consume this file.
+//
+// Each Crst type definition is currently in alphabetical order. Please maintain this convention.
+//
+
+Crst AllowedFiles
+ AcquiredBefore JumpStubCache UniqueStack
+End
+
+Crst AppDomainCache
+ AcquiredBefore UniqueStack UnresolvedClassLock
+End
+
+Crst AppDomainHandleTable
+ AcquiredBefore AvailableParamTypes HandleTable IbcProfile SyncBlockCache SystemDomainDelayedUnloadList
+ ThreadStore SystemDomain
+End
+
+Crst ArgBasedStubCache
+End
+
+Crst AssemblyIdentityCache
+End
+
+Crst AssemblyLoader
+ AcquiredBefore DeadlockDetection UniqueStack
+End
+
+Crst AvailableClass
+ AcquiredBefore LoaderHeap
+End
+
+Crst AssemblyDependencyGraph
+End
+
+Crst AvailableParamTypes
+ AcquiredBefore IbcProfile LoaderHeap
+End
+
+Crst BaseDomain
+ AcquiredBefore LoaderHeap UniqueStack
+End
+
+Crst CCompRC
+ Unordered
+End
+
+Crst Cer
+ AcquiredBefore JumpStubCache UniqueStack
+End
+
+Crst ClassFactInfoHash
+ AcquiredBefore SyncBlockCache ThreadStore
+End
+
+Crst ClassInit
+ AcquiredBefore DeadlockDetection IbcProfile
+ SameLevelAs Jit
+End
+
+Crst ClrNotification
+ Unordered
+End
+
+Crst CrstCLRPrivBinderLocalWinMDPath
+End
+
+Crst CLRPrivBinderMaps
+End
+
+Crst CLRPrivBinderMapsAdd
+ AcquiredBefore CLRPrivBinderMaps
+End
+
+Crst COMWrapperCache
+ AcquiredBefore HandleTable UniqueStack
+End
+
+Crst ConnectionNameTable
+End
+
+Crst Contexts
+ AcquiredBefore AvailableParamTypes Cer ClassInit DeadlockDetection DomainLocalBlock FuncPtrStubs
+ GlobalStrLiteralMap Jit LoaderHeap ModuleLookupTable RWLock SigConvert SingleUseLock
+ StubUnwindInfoHeapSegments SyncBlockCache TypeIDMap UnresolvedClassLock
+End
+
+Crst CoreCLRBinderLog
+ Unordered
+End
+
+Crst CSPCache
+ AcquiredBefore JumpStubCache
+End
+
+Crst DeadlockDetection
+End
+
+Crst DebuggerController
+ // AcquiredBefore DebuggerHeapLock DebuggerJitInfo LoaderHeap
+
+ // See bug: 581892. This has a conflict with CrstInstMethodHashTableRanking.
+ // The controller logic will be moved to OOP in V3, and so this lock will no longer be necessary.
+ // Fixing this in-proc would be difficult, and it would all be throwaway as we go oop.
+ Unordered
+End
+
+// This is a leaf debugger lock.
+Crst DebuggerFavorLock
+ AcquiredAfter DebuggerJitInfo DebuggerMutex
+End
+
+// This is the lock used by the DebuggerHeapExecutableMemoryAllocator for allocating/freeing memory.
+Crst DebuggerHeapExecMemLock
+End
+
+// Debugger Heap lock is the smallest of the debugger locks.
+Crst DebuggerHeapLock
+ AcquiredAfter DebuggerFavorLock DebuggerJitInfo DebuggerMutex
+ // Disabled per bug 581892
+ // AcquiredAfter DebuggerController
+End
+
+Crst DebuggerJitInfo
+ AcquiredBefore DebuggerHeapLock
+End
+
+// This is the major debugger lock.
+// It's the largest of the debugger locks.
+Crst DebuggerMutex
+ AcquiredBefore AvailableParamTypes ConnectionNameTable
+ DynamicIL LoaderHeap ModuleLookupTable
+
+ // Disabled per bug 581892
+ // AcquiredBefore DebuggerController
+ AcquiredBefore DebuggerHeapLock DebuggerJitInfo
+
+End
+
+// This lock is used only for testing data consistency (see code:DataTest::TestDataSafety)
+// and is released before taking any other lock except for CrstDataTest2
+Crst DataTest1
+ AcquiredAfter DebuggerMutex
+End
+
+// This lock is used only for testing data consistency (see code:DataTest::TestDataSafety)
+// and is released before taking any other lockCrst DataTest2
+Crst DataTest2
+ AcquiredAfter DataTest1
+End
+
+
+Crst DbgTransport
+End
+
+Crst DelegateToFPtrHash
+End
+
+Crst DomainLocalBlock
+ AcquiredBefore AppDomainHandleTable IbcProfile LoaderHeap SystemDomainDelayedUnloadList UniqueStack
+End
+
+Crst DynamicIL
+End
+
+Crst DynamicMT
+ AcquiredBefore IbcProfile
+End
+
+Crst DynLinkZapItems
+ AcquiredBefore LoaderHeap
+End
+
+Crst EventStore
+End
+
+Crst Exception
+End
+
+Crst ExecuteManLock
+ AcquiredBefore UniqueStack
+End
+
+Crst ExecuteManRangeLock
+End
+
+Crst FCall
+ AcquiredBefore LoaderHeap
+End
+
+Crst RetThunkCache
+ AcquiredBefore LoaderHeap
+End
+
+Crst FriendAccessCache
+ AcquiredBefore JumpStubCache UniqueStack
+End
+
+Crst FuncPtrStubs
+ AcquiredBefore IbcProfile LoaderHeap UniqueStack CodeFragmentHeap JumpStubCache PatchEntryPoint
+End
+
+Crst FusionAppCtx
+ AcquiredBefore PEImage
+End
+
+Crst NativeBinderInit
+ Unordered
+End
+
+Crst NativeImageCache
+ Unordered
+End
+
+Crst GCCover
+ AcquiredBefore LoaderHeap ReJITDomainTable
+End
+
+Crst GCMemoryPressure
+End
+
+Crst GlobalStrLiteralMap
+ AcquiredBefore HandleTable IbcProfile SyncBlockCache SystemDomainDelayedUnloadList ThreadStore UniqueStack
+End
+
+Crst HandleTable
+ SameLevelAs HandleTable
+End
+
+Crst HostAssemblyMap
+End
+
+Crst HostAssemblyMapAdd
+ AcquiredBefore HostAssemblyMap
+End
+
+Crst IbcProfile
+End
+
+Crst IJWFixupData
+ AcquiredBefore FuncPtrStubs IJWHash LoaderHeap
+End
+
+Crst IJWHash
+End
+
+Crst ILStubGen
+ AcquiredBefore DeadlockDetection UniqueStack
+End
+
+Crst InstMethodHashTable
+ AcquiredBefore LoaderHeap UniqueStack JumpStubCache
+End
+
+Crst InterfaceVTableMap
+End
+
+Crst Interop
+ AcquiredBefore AppDomainHandleTable AvailableParamTypes Cer ClassInit DeadlockDetection DomainLocalBlock
+ HandleTable InstMethodHashTable InteropData JitGenericHandleCache LoaderHeap SigConvert
+ StubDispatchCache StubUnwindInfoHeapSegments SyncBlockCache TypeIDMap UnresolvedClassLock
+End
+
+Crst InteropData
+ AcquiredBefore LoaderHeap UniqueStack
+End
+
+Crst IOThreadpoolWorker
+ AcquiredBefore ThreadIdDispenser ThreadStore
+End
+
+Crst IsJMCMethod
+End
+
+Crst ISymUnmanagedReader
+ AcquiredBefore PEImagePDBStream UniqueStack JumpStubCache
+End
+
+Crst Jit
+ AcquiredBefore DeadlockDetection JumpStubCache
+ SameLevelAs ClassInit
+End
+
+Crst JitGenericHandleCache
+End
+
+Crst JitPerf
+ Unordered
+End
+
+Crst JumpStubCache
+ AcquiredBefore ExecuteManRangeLock LoaderHeap SingleUseLock
+ AcquiredAfter AppDomainCache ExecuteManLock
+ ILStubGen ThreadpoolTimerQueue ThreadpoolWaitThreads
+ TPMethodTable TypeIDMap BaseDomain AssemblyLoader
+End
+
+Crst ListLock
+ Unordered
+End
+
+// Leaflock leveling, used for crsts that explicitly want to be a leaf lock
+Crst LeafLock
+End
+
+Crst LoaderAllocator
+ AcquiredBefore AppDomainHandleTable HandleTable UniqueStack ThreadStore
+ AcquiredAfter DomainLocalBlock
+End
+
+Crst LoaderAllocatorReferences
+ AcquiredBefore LoaderAllocator
+ AcquiredAfter PendingTypeLoadEntry InstMethodHashTable
+End
+
+Crst AssemblyList
+ AcquiredAfter LoaderAllocatorReferences ThreadStore AssemblyLoader
+End
+
+Crst LoaderHeap
+End
+
+Crst Mda
+End
+
+Crst MetadataTracker
+ Unordered
+End
+
+Crst StubCache
+ AcquiredBefore LoaderHeap
+End
+
+Crst ModIntPairList
+End
+
+Crst Module
+ AcquiredBefore LoaderHeap UniqueStack
+End
+
+Crst ModuleFixup
+ AcquiredBefore AppDomainHandleTable GlobalStrLiteralMap IbcProfile SyncBlockCache
+End
+
+Crst ModuleLookupTable
+ AcquiredBefore LoaderHeap
+End
+
+Crst MUThunkHash
+End
+
+Crst Nls
+End
+
+Crst ObjectList
+ SameLevelAs ObjectList
+End
+
+Crst OnEventManager
+End
+
+Crst PatchEntryPoint
+End
+
+Crst PEImage
+ AcquiredBefore UniqueStack
+End
+
+Crst PEImagePDBStream
+End
+
+Crst PendingTypeLoadEntry
+ AcquiredBefore AppDomainCache AppDomainHandleTable AssemblyLoader AvailableClass AvailableParamTypes
+ BaseDomain ClassInit DeadlockDetection DebuggerController DebuggerJitInfo DebuggerMutex
+ DomainLocalBlock DynLinkZapItems Exception ExecuteManRangeLock FuncPtrStubs
+ FusionAppCtx GlobalStrLiteralMap HandleTable IbcProfile
+ IJWFixupData IJWHash ISymUnmanagedReader Jit JumpStubCache LoaderHeap ModIntPairList
+ Module ModuleLookupTable PEImage SecurityStackwalkCache SharedAssemblyCreate
+ SigConvert SingleUseLock StubDispatchCache StubUnwindInfoHeapSegments
+ SyncBlockCache SystemDomain ThreadIdDispenser ThreadStore TypeIDMap UnresolvedClassLock
+ SameLevelAs PendingTypeLoadEntry
+End
+
+Crst PinHandle
+End
+
+// ProfilerGCRefDataFreeList synchronizes access to the profiler API's list of
+// free, previously allocated structures that track moved references and
+// root references during a GC.
+Crst ProfilerGCRefDataFreeList
+End
+
+// ProfilingAPIStatus serializes attempts to transition the global status
+// from state to state, and access to the ProfilerDetachInfo structure
+// between the thread executing DetachProfiler(), and the DetachThread
+// carrying out the evacuation order.
+Crst ProfilingAPIStatus
+End
+
+Crst PublisherCertificate
+End
+
+Crst RCWCache
+ AcquiredBefore IbcProfile LoaderHeap RCWCleanupList
+End
+
+Crst RCWRefCache
+ AcquiredBefore HandleTable
+End
+
+Crst RCWCleanupList
+End
+
+Crst ReDacl
+End
+
+Crst Reflection
+ AcquiredBefore LoaderHeap UnresolvedClassLock
+End
+
+// Used to synchronize all rejit information stored in a given AppDomain.
+Crst ReJITDomainTable
+ AcquiredBefore LoaderHeap SingleUseLock DeadlockDetection JumpStubCache DebuggerController FuncPtrStubs
+ AcquiredAfter ReJITGlobalRequest ThreadStore GlobalStrLiteralMap SystemDomain DebuggerMutex MethodDescBackpatchInfoTracker
+End
+
+// Used to synchronize all global requests (which may span multiple AppDomains) which add
+// new functions to rejit tables, or request Reverts on existing functions in the rejit
+// tables. One of these crsts exist per runtime.
+Crst ReJITGlobalRequest
+ AcquiredBefore ThreadStore ReJITDomainTable SystemDomain
+End
+
+// ETW infrastructure uses this crst to protect a hash table of TypeHandles which is
+// used to remember which types have been logged (to avoid duplicate logging of the
+// same type).
+Crst EtwTypeLogHash
+ AcquiredAfter ThreadStore AllowedFiles Cer TPMethodTable
+ AcquiredBefore AvailableParamTypes ConnectionNameTable DeadlockDetection DebuggerController
+ DebuggerHeapLock DebuggerJitInfo DynamicIL ExecuteManRangeLock HandleTable IbcProfile
+ JitGenericHandleCache JumpStubCache LoaderHeap ModuleLookupTable ProfilingAPIStatus
+ ProfilerGCRefDataFreeList RWLock SingleUseLock SyncBlockCache SystemDomainDelayedUnloadList
+ ThreadIdDispenser ThreadStaticDataHashTable
+End
+
+Crst Remoting
+ AcquiredBefore AppDomainHandleTable AvailableParamTypes Cer ClassInit DeadlockDetection DebuggerController
+ DebuggerHeapLock DebuggerJitInfo DebuggerMutex DomainLocalBlock ExecuteManRangeLock
+ FuncPtrStubs GlobalStrLiteralMap HandleTable InstMethodHashTable Jit JitGenericHandleCache
+ JumpStubCache LoaderHeap StubCache Module ModuleLookupTable SecurityStackwalkCache SigConvert
+ SingleUseLock StubUnwindInfoHeapSegments SyncBlockCache SystemDomainDelayedUnloadList
+ ThreadStore UnresolvedClassLock PendingTypeLoadEntry
+End
+
+Crst RWLock
+End
+
+Crst SavedExceptionInfo
+ AcquiredBefore DebuggerController
+End
+
+Crst SaveModuleProfileData
+End
+
+Crst SecurityStackwalkCache
+End
+
+Crst SharedAssemblyCreate
+ AcquiredBefore DeadlockDetection UniqueStack
+End
+
+Crst SigConvert
+ AcquiredBefore LoaderHeap
+End
+
+Crst SingleUseLock
+ AcquiredBefore ExecuteManRangeLock LoaderHeap UniqueStack DebuggerJitInfo
+End
+
+Crst UnwindInfoTableLock
+ AcquiredAfter StubUnwindInfoHeapSegments SingleUseLock
+ AcquiredBefore StressLog
+End
+
+Crst SpecialStatics
+End
+
+Crst StressLog
+ Unordered
+End
+
+Crst StrongName
+End
+
+Crst CodeFragmentHeap
+ AcquiredBefore SingleUseLock
+End
+
+Crst StubDispatchCache
+End
+
+Crst StubUnwindInfoHeapSegments
+ AcquiredAfter StubCache
+End
+
+Crst SyncBlockCache
+ AcquiredBefore ThreadIdDispenser
+End
+
+Crst SyncHashLock
+End
+
+Crst SystemBaseDomain
+ AcquiredBefore LoaderHeap UniqueStack
+End
+
+Crst SystemDomain
+ AcquiredBefore DebuggerMutex HandleTable IbcProfile SaveModuleProfileData
+ ThreadIdDispenser ThreadStore
+End
+
+Crst SystemDomainDelayedUnloadList
+End
+
+Crst ThreadIdDispenser
+End
+
+Crst ThreadpoolEventCache
+End
+
+Crst ThreadpoolTimerQueue
+ AcquiredBefore UniqueStack
+End
+
+Crst ThreadpoolWaitThreads
+ AcquiredBefore UniqueStack
+End
+
+Crst ThreadpoolWorker
+ AcquiredBefore ThreadIdDispenser ThreadStore
+End
+
+Crst ThreadStaticDataHashTable
+ AcquiredBefore SyncBlockCache
+End
+
+Crst ThreadStore
+ AcquiredBefore AvailableParamTypes ConnectionNameTable DeadlockDetection DebuggerController
+ DebuggerHeapLock DebuggerJitInfo DynamicIL ExecuteManRangeLock HandleTable IbcProfile
+ JitGenericHandleCache JumpStubCache LoaderHeap ModuleLookupTable ProfilingAPIStatus
+ ProfilerGCRefDataFreeList RWLock SingleUseLock SyncBlockCache SystemDomainDelayedUnloadList
+ ThreadIdDispenser ThreadStaticDataHashTable DebuggerMutex
+End
+
+Crst TPMethodTable
+ AcquiredBefore DebuggerHeapLock LoaderHeap UniqueStack AvailableParamTypes
+End
+
+Crst TypeIDMap
+ AcquiredBefore UniqueStack
+End
+
+Crst TypeEquivalenceMap
+ AcquiredBefore LoaderHeap
+End
+
+Crst UMThunkHash
+End
+
+Crst UniqueStack
+ AcquiredBefore LoaderHeap
+End
+
+Crst UnresolvedClassLock
+ AcquiredBefore AvailableParamTypes DynLinkZapItems IbcProfile JumpStubCache
+End
+
+Crst WrapperTemplate
+ AcquiredBefore IbcProfile
+End
+
+Crst UMEntryThunkCache
+ AcquiredBefore LoaderHeap
+End
+
+Crst PinnedByrefValidation
+End
+
+Crst VSDIndirectionCellLock
+ AcquiredBefore LoaderHeap
+End
+
+Crst MulticoreJitHash
+End
+
+Crst MulticoreJitManager
+ AcquiredBefore MulticoreJitHash ThreadStore
+End
+
+Crst WinRTFactoryCache
+ AcquiredBefore HandleTable
+End
+
+Crst SqmManager
+End
+
+Crst StackSampler
+End
+
+Crst InlineTrackingMap
+ AcquiredBefore IbcProfile
+End
+
+Crst JitInlineTrackingMap
+ AcquiredBefore ReJITDomainTable ThreadStore LoaderAllocator
+End
+
+Crst EventPipe
+ AcquiredAfter PendingTypeLoadEntry
+ AcquiredBefore ThreadIdDispenser ThreadStore DomainLocalBlock InstMethodHashTable
+End
+
+Crst NotifyGdb
+End
+
+Crst ReadyToRunEntryPointToMethodDescMap
+ AcquiredBefore ExecuteManRangeLock UniqueStack
+End
+
+Crst TieredCompilation
+ AcquiredBefore ThreadpoolTimerQueue
+End
+
+Crst COMCallWrapper
+End
+
+Crst MethodDescBackpatchInfoTracker
+ AcquiredBefore FuncPtrStubs ThreadStore SystemDomain
+ AcquiredAfter ReJITGlobalRequest
+End
diff --git a/lib/coreclr/src/inc/MSCOREE.IDL b/lib/coreclr/src/inc/MSCOREE.IDL
new file mode 100644
index 0000000000..ce368f3f80
--- /dev/null
+++ b/lib/coreclr/src/inc/MSCOREE.IDL
@@ -0,0 +1,326 @@
+// 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.
+//
+
+//
+/**************************************************************************************
+ ** **
+ ** Mscoree.idl - interface definitions for mscoree.dll **
+ ** **
+ **************************************************************************************/
+
+cpp_quote("#define DECLARE_DEPRECATED ")
+cpp_quote("#define DEPRECATED_CLR_STDAPI STDAPI")
+
+cpp_quote("")
+
+//
+// Interface descriptions
+//
+import "unknwn.idl";
+
+cpp_quote("struct IActivationFactory;")
+interface IActivationFactory;
+
+cpp_quote("struct IHostControl;")
+interface IHostControl;
+
+cpp_quote("struct ICLRControl;")
+interface ICLRControl;
+
+// CLSID ComCallUnmarshal2
+cpp_quote("EXTERN_GUID(CLSID_ComCallUnmarshalV4, 0x45fb4600,0xe6e8,0x4928,0xb2,0x5e,0x50,0x47,0x6f,0xf7,0x94,0x25);")
+
+// IID ICLRRuntimeHost: uuid(90F1A06C-7712-4762-86B5-7A5EBA6BDB02)
+cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);")
+
+// IID ICLRRuntimeHost2: uuid(712AB73F-2C22-4807-AD7E-F501D7B72C2D)
+cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHost2, 0x712AB73F, 0x2C22, 0x4807, 0xAD, 0x7E, 0xF5, 0x01, 0xD7, 0xb7, 0x2C, 0x2D);")
+
+// IID ICLRRuntimeHost4: uuid(64F6D366-D7C2-4F1F-B4B2-E8160CAC43AF)
+cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHost4, 0x64F6D366, 0xD7C2, 0x4F1F, 0xB4, 0xB2, 0xE8, 0x16, 0x0C, 0xAC, 0x43, 0xAF);")
+
+#pragma midl_echo("typedef HRESULT (STDAPICALLTYPE *FnGetCLRRuntimeHost)(REFIID riid, IUnknown **pUnk);")
+
+typedef HRESULT (__stdcall *FExecuteInAppDomainCallback) (void* cookie);
+
+// By default GC is concurrent and only the base system library is loaded into the domain-neutral area.
+typedef enum {
+ STARTUP_CONCURRENT_GC = 0x1,
+
+ STARTUP_LOADER_OPTIMIZATION_MASK = 0x3<<1, // loader optimization mask
+ STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN = 0x1<<1, // no domain neutral loading
+ STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN = 0x2<<1, // all domain neutral loading
+ STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST = 0x3<<1, // strong name domain neutral loading
+
+
+ STARTUP_LOADER_SAFEMODE = 0x10, // Do not apply runtime version policy to the version passed in
+ STARTUP_LOADER_SETPREFERENCE = 0x100, // Set preferred runtime. Do not actally start it
+
+ STARTUP_SERVER_GC = 0x1000, // Use server GC
+ STARTUP_HOARD_GC_VM = 0x2000, // GC keeps virtual address used
+ STARTUP_SINGLE_VERSION_HOSTING_INTERFACE = 0x4000, // Disallow mixing hosting interface
+ STARTUP_LEGACY_IMPERSONATION = 0x10000, // Do not flow impersonation across async points by default
+ STARTUP_DISABLE_COMMITTHREADSTACK = 0x20000, // Don't eagerly commit thread stack
+ STARTUP_ALWAYSFLOW_IMPERSONATION = 0x40000, // Force flow impersonation across async points
+ // (impersonations achieved thru p/invoke and managed will flow.
+ // default is to flow only managed impersonation)
+ STARTUP_TRIM_GC_COMMIT = 0x80000, // GC uses less committed space when system memory low
+ STARTUP_ETW = 0x100000,
+ STARTUP_ARM = 0x400000, // Enable the ARM feature.
+ STARTUP_SINGLE_APPDOMAIN = 0x800000, // application runs in default domain, no more domains are created
+ STARTUP_APPX_APP_MODEL = 0x1000000, // jupiter app
+ STARTUP_DISABLE_RANDOMIZED_STRING_HASHING = 0x2000000 // Disable the randomized string hashing (not supported)
+} STARTUP_FLAGS;
+
+typedef enum
+{
+ APPDOMAIN_SECURITY_DEFAULT =0x0,
+ APPDOMAIN_SECURITY_SANDBOXED = 0x1, // appdomain is sandboxed
+ APPDOMAIN_SECURITY_FORBID_CROSSAD_REVERSE_PINVOKE = 0x2, // no cross ad reverse pinvokes
+ APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS = 0x4, //
+ APPDOMAIN_FORCE_TRIVIAL_WAIT_OPERATIONS = 0x08, // do not pump messages during wait operations, do not call sync context
+ // When passed by the host, this flag will allow any assembly to perform PInvoke or COMInterop operations.
+ // Otherwise, by default, only platform assemblies can perform those operations.
+ APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP = 0x10,
+
+ APPDOMAIN_ENABLE_PLATFORM_SPECIFIC_APPS = 0x40,
+ APPDOMAIN_ENABLE_ASSEMBLY_LOADFILE = 0x80,
+
+ APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT = 0x100,
+} APPDOMAIN_SECURITY_FLAGS;
+
+typedef enum {
+ WAIT_MSGPUMP = 0x1,
+ WAIT_ALERTABLE = 0x2,
+ WAIT_NOTINDEADLOCK = 0x4
+}WAIT_OPTION;
+
+typedef enum ETaskType
+{
+ TT_DEBUGGERHELPER = 0x1,
+ TT_GC = 0x2,
+ TT_FINALIZER = 0x4,
+ TT_THREADPOOL_TIMER = 0x8,
+ TT_THREADPOOL_GATE = 0x10,
+ TT_THREADPOOL_WORKER = 0x20,
+ TT_THREADPOOL_IOCOMPLETION = 0x40,
+ TT_ADUNLOAD = 0x80,
+ TT_USER = 0x100,
+ TT_THREADPOOL_WAIT = 0x200,
+
+ TT_UNKNOWN = 0x80000000,
+} ETaskType;
+
+typedef enum {
+ // Default to minidump
+ DUMP_FLAVOR_Mini = 0,
+
+ // Include critical CLR state
+ DUMP_FLAVOR_CriticalCLRState = 1,
+
+ // Include critical CLR state and ngen images without including hosted heap
+ // It is host's responsibility to report hosted heap.
+ DUMP_FLAVOR_NonHeapCLRState = 2,
+
+ DUMP_FLAVOR_Default = DUMP_FLAVOR_Mini
+
+} ECustomDumpFlavor;
+
+const DWORD BucketParamsCount = 10;
+const DWORD BucketParamLength = 255;
+
+// used for indexing into BucketParameters::pszParams
+typedef enum
+{
+ Parameter1 = 0,
+ Parameter2,
+ Parameter3,
+ Parameter4,
+ Parameter5,
+ Parameter6,
+ Parameter7,
+ Parameter8,
+ Parameter9,
+ InvalidBucketParamIndex
+} BucketParameterIndex;
+
+typedef struct _BucketParameters
+{
+ BOOL fInited; // Set to TRUE if the rest of this structure is valid.
+ WCHAR pszEventTypeName[BucketParamLength]; // Name of the event type.
+ WCHAR pszParams[BucketParamsCount][BucketParamLength]; // Parameter strings.
+} BucketParameters;
+
+
+typedef enum
+{
+ OPR_ThreadAbort,
+ OPR_ThreadRudeAbortInNonCriticalRegion,
+ OPR_ThreadRudeAbortInCriticalRegion,
+ OPR_AppDomainUnload,
+ OPR_AppDomainRudeUnload,
+ OPR_ProcessExit,
+ OPR_FinalizerRun,
+ MaxClrOperation
+ // Do not add anything after this
+} EClrOperation;
+
+typedef enum
+{
+ FAIL_NonCriticalResource,
+ FAIL_CriticalResource,
+ FAIL_FatalRuntime,
+ FAIL_OrphanedLock,
+ FAIL_StackOverflow,
+ // In CoreCLR, we will treat AV specially, based upon the escalation policy.
+ // Currently only used in CoreCLR.
+ FAIL_AccessViolation,
+ FAIL_CodeContract,
+ MaxClrFailure
+ // Do not add anything after this
+} EClrFailure;
+
+typedef enum
+{
+ eRuntimeDeterminedPolicy, // default
+ eHostDeterminedPolicy, // revert back to Everett behavior, i.e. swallow all exception
+} EClrUnhandledException;
+
+typedef enum
+{
+ // !!! Please keep these ordered by severity
+ // !!! If you don't, you need to change EEPolicy::IsValidActionForOperation
+ // !!! and EEPolicy::IsValidActionForFailure
+ eNoAction,
+ eThrowException,
+ eAbortThread,
+ eRudeAbortThread,
+ eUnloadAppDomain,
+ eRudeUnloadAppDomain,
+ eExitProcess,
+ // Look at CorHost2::Stop. For eFastExitProcess, eRudeExitProcess, eDisableRuntime,
+ // Stop bypasses finalizer run.
+ eFastExitProcess,
+ eRudeExitProcess,
+ MaxPolicyAction
+} EPolicyAction;
+
+
+//*****************************************************************************
+// New interface for hosting mscoree
+//*****************************************************************************
+[
+ uuid(90F1A06C-7712-4762-86B5-7A5EBA6BDB02),
+ version(1.0),
+ helpstring("Common Language Runtime Hosting Interface"),
+ pointer_default(unique),
+ local
+]
+interface ICLRRuntimeHost : IUnknown
+{
+ // Starts the runtime. This is equivalent to CoInitializeCor().
+ HRESULT Start();
+
+ // Terminates the runtime, This is equivalent CoUninitializeCor();
+ HRESULT Stop();
+
+ // Returns an object for configuring runtime, e.g. threading, lock
+ // prior it starts. If the runtime has been initialized this
+ // routine returns an error. See IHostControl.
+ HRESULT SetHostControl([in] IHostControl* pHostControl);
+
+ HRESULT GetCLRControl([out] ICLRControl** pCLRControl);
+
+ HRESULT UnloadAppDomain([in] DWORD dwAppDomainId,
+ [in] BOOL fWaitUntilDone);
+
+ HRESULT ExecuteInAppDomain([in] DWORD dwAppDomainId,
+ [in] FExecuteInAppDomainCallback pCallback,
+ [in] void* cookie);
+
+ HRESULT GetCurrentAppDomainId([out] DWORD *pdwAppDomainId);
+
+ HRESULT ExecuteApplication([in] LPCWSTR pwzAppFullName,
+ [in] DWORD dwManifestPaths,
+ [in] LPCWSTR *ppwzManifestPaths, // optional
+ [in] DWORD dwActivationData,
+ [in] LPCWSTR *ppwzActivationData, // optional
+ [out] int *pReturnValue);
+
+ HRESULT ExecuteInDefaultAppDomain([in] LPCWSTR pwzAssemblyPath,
+ [in] LPCWSTR pwzTypeName,
+ [in] LPCWSTR pwzMethodName,
+ [in] LPCWSTR pwzArgument,
+ [out] DWORD *pReturnValue);
+};
+
+//*****************************************************************************
+// New interface for hosting mscoree
+//*****************************************************************************
+[
+ object,
+ uuid(712AB73F-2C22-4807-AD7E-F501D7B72C2D),
+ version(2.0),
+ helpstring("Common Language Runtime Hosting Interface"),
+ pointer_default(unique),
+ local
+]
+interface ICLRRuntimeHost2 : ICLRRuntimeHost
+{
+ // Creates an app domain (sandboxed or not) with the given manager class and the given
+ // set of properties.
+ HRESULT CreateAppDomainWithManager([in] LPCWSTR wszFriendlyName,
+ [in] DWORD dwFlags,
+ [in] LPCWSTR wszAppDomainManagerAssemblyName,
+ [in] LPCWSTR wszAppDomainManagerTypeName,
+ [in] int nProperties,
+ [in] LPCWSTR* pPropertyNames,
+ [in] LPCWSTR* pPropertyValues,
+ [out] DWORD* pAppDomainID);
+
+ HRESULT CreateDelegate([in] DWORD appDomainID,
+ [in] LPCWSTR wszAssemblyName,
+ [in] LPCWSTR wszClassName,
+ [in] LPCWSTR wszMethodName,
+ [out] INT_PTR* fnPtr);
+
+ // Authenticates a host based upon a key value. No longer required.
+ HRESULT Authenticate([in] ULONGLONG authKey);
+
+ // Ensures CLR-set Mac (Mach) EH port is registered.
+ HRESULT RegisterMacEHPort();
+
+ HRESULT SetStartupFlags([in] STARTUP_FLAGS dwFlags);
+
+ HRESULT DllGetActivationFactory([in] DWORD appDomainID,
+ [in] LPCWSTR wszTypeName,
+ [out] IActivationFactory ** factory);
+
+ HRESULT ExecuteAssembly([in] DWORD dwAppDomainId,
+ [in] LPCWSTR pwzAssemblyPath,
+ [in] int argc,
+ [in] LPCWSTR* argv,
+ [out] DWORD *pReturnValue);
+
+};
+
+[
+ object,
+ uuid(64F6D366-D7C2-4F1F-B4B2-E8160CAC43AF),
+ version(4.0),
+ helpstring("Common Language Runtime Hosting Interface"),
+ pointer_default(unique),
+ local
+]
+interface ICLRRuntimeHost4 : ICLRRuntimeHost2
+{
+ HRESULT UnloadAppDomain2([in] DWORD dwAppDomainId,
+ [in] BOOL fWaitUntilDone,
+ [out] int *pLatchedExitCode);
+};
+
+cpp_quote("#undef DEPRECATED_CLR_STDAPI")
+cpp_quote("#undef DECLARE_DEPRECATED")
+cpp_quote("#undef DEPRECATED_CLR_API_MESG")
diff --git a/lib/coreclr/src/inc/OpCodeGen.pl b/lib/coreclr/src/inc/OpCodeGen.pl
new file mode 100644
index 0000000000..64ba130da4
--- /dev/null
+++ b/lib/coreclr/src/inc/OpCodeGen.pl
@@ -0,0 +1,483 @@
+# 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.
+#
+# OpCodeGen.pl
+#
+# PERL script used to generate the numbering of the reference opcodes
+#
+#use strict 'vars';
+#use strict 'subs';
+#use strict 'refs';
+
+
+my $ret = 0;
+my %opcodeEnum;
+my %oneByte;
+my %twoByte;
+my %controlFlow;
+my @singleByteArg;
+my %stackbehav;
+my %opcodetype;
+my %operandtype;
+my %opcodes;
+my $popstate;
+my $pushstate;
+
+$ctrlflowcount = 0;
+
+$count = 0;
+
+my @lowercaseAlphabet = ('a'..'z','0'..'9');
+my %upcaseAlphabet = ();
+
+foreach $letter (@lowercaseAlphabet) {
+ $j = $letter;
+ $j=~tr/a-z/A-Z/;
+ $upcaseAlphabet{$letter}=$j;
+}
+
+$license = "// Licensed to the .NET Foundation under one or more agreements.\n";
+$license .= "// The .NET Foundation licenses this file to you under the MIT license.\n";
+$license .= "// See the LICENSE file in the project root for more information.\n\n";
+
+$startHeaderComment = "/*============================================================\n**\n";
+$endHeaderComment = "**\n** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!\n";
+$endHeaderComment .= "** See \$(RepoRoot)\\src\\inc\\OpCodeGen.pl for more information.**\n";
+$endHeaderComment .= "==============================================================*/\n\n";
+
+$usingAndRefEmitNmsp = "namespace System.Reflection.Emit\n{\n\n";
+$obsoleteAttr = " [Obsolete(\"This API has been deprecated. https://go.microsoft.com/fwlink/?linkid=14202\")]\n";
+
+# Open source file and target files
+
+open (OPCODE, "opcode.def") or die "Couldn't open opcode.def: $!\n";
+open (OUTPUT, ">OpCodes.cs") or die "Couldn't open OpCodes.cs: $!\n";
+open (FCOUTPUT, ">FlowControl.cs") or die "Couldn't open FlowControl.cs: $!\n";
+open (SOUTPUT, ">StackBehaviour.cs") or die "Couldn't open StackBehaviour.cs: $!\n";
+open (OCOUTPUT, ">OpCodeType.cs") or die "Couldn't open OpCodeType.cs: $!\n";
+open (OPOUTPUT, ">OperandType.cs") or die "Couldn't open OperandType.cs: $!\n";
+
+print OUTPUT $license;
+print OUTPUT $startHeaderComment;
+print OUTPUT "** Class: OpCodes\n";
+print OUTPUT "**\n";
+print OUTPUT "** Purpose: Exposes all of the IL instructions supported by the runtime.\n";
+print OUTPUT $endHeaderComment;
+
+print OUTPUT $usingAndRefEmitNmsp;
+
+print FCOUTPUT $license;
+print FCOUTPUT $startHeaderComment;
+print FCOUTPUT "** Enumeration: FlowControl\n";
+print FCOUTPUT "**\n";
+print FCOUTPUT "** Purpose: Exposes FlowControl Attribute of IL.\n";
+print FCOUTPUT $endHeaderComment;
+
+print FCOUTPUT $usingAndRefEmitNmsp;
+print FCOUTPUT " public enum FlowControl\n {\n";
+
+print SOUTPUT $license;
+print SOUTPUT $startHeaderComment;
+print SOUTPUT "** Enumeration: StackBehaviour\n";
+print SOUTPUT "**\n";
+print SOUTPUT "** Purpose: Exposes StackBehaviour Attribute of IL.\n";
+print SOUTPUT $endHeaderComment;
+
+print SOUTPUT $usingAndRefEmitNmsp;
+print SOUTPUT " public enum StackBehaviour\n {\n";
+
+print OCOUTPUT $license;
+print OCOUTPUT $startHeaderComment;
+print OCOUTPUT "** Enumeration: OpCodeType\n";
+print OCOUTPUT "**\n";
+print OCOUTPUT "** Purpose: Exposes OpCodeType Attribute of IL.\n";
+print OCOUTPUT $endHeaderComment;
+
+print OCOUTPUT $usingAndRefEmitNmsp;
+print OCOUTPUT " public enum OpCodeType\n {\n";
+
+print OPOUTPUT $license;
+print OPOUTPUT $startHeaderComment;
+print OPOUTPUT "** Enumeration: OperandType\n";
+print OPOUTPUT "**\n";
+print OPOUTPUT "** Purpose: Exposes OperandType Attribute of IL.\n";
+print OPOUTPUT $endHeaderComment;
+
+print OPOUTPUT $usingAndRefEmitNmsp;
+print OPOUTPUT " public enum OperandType\n {\n";
+
+while ()
+{
+ # Process only OPDEF(....) lines
+ if (/OPDEF\(\s*/)
+ {
+ chop; # Strip off trailing CR
+ s/^OPDEF\(\s*//; # Strip off "OP("
+ s/,\s*/,/g; # Remove whitespace
+ s/\).*$//; # Strip off ")" and everything behind it at end
+
+ # Split the line up into its basic parts
+ ($enumname, $stringname, $pop, $push, $operand, $type, $size, $s1, $s2, $ctrl) = split(/,/);
+ $s1 =~ s/0x//;
+ $s1 = hex($s1);
+ $s2 =~ s/0x//;
+ $s2 = hex($s2);
+
+ if ($size == 0)
+ {
+ next;
+ }
+
+ next if ($enumname =~ /UNUSED/);
+
+ #Remove the prefix
+ $enumname=~s/CEE_//g;
+
+ #Convert name to our casing convention
+ $enumname=~tr/A-Z/a-z/;
+ $enumname=~s/^(.)/\u$1/g;
+ $enumname=~s/_(.)/_\u$1/g;
+
+ #Convert pop to our casing convention
+ $pop=~tr/A-Z/a-z/;
+ $pop=~s/^(.)/\u$1/g;
+ $pop=~s/_(.)/_\u$1/g;
+
+ #Convert push to our casing convention
+ $push=~tr/A-Z/a-z/;
+ $push=~s/^(.)/\u$1/g;
+ $push=~s/_(.)/_\u$1/g;
+
+ #Convert operand to our casing convention
+ #$operand=~tr/A-Z/a-z/;
+ #$operand=~s/^(.)/\u$1/g;
+ #$operand=~s/_(.)/_\u$1/g;
+
+ #Remove the I prefix on type
+ $type=~s/I//g;
+
+ #Convert Type to our casing convention
+ $type=~tr/A-Z/a-z/;
+ $type=~s/^(.)/\u$1/g;
+ $type=~s/_(.)/_\u$1/g;
+
+ #Convert ctrl to our casing convention
+ $ctrl=~tr/A-Z/a-z/;
+ $ctrl=~s/^(.)/\u$1/g;
+ $ctrl=~s/_(.)/_\u$1/g;
+
+ # Make a list of the flow Control type
+
+ # Make a list of the opcodes and their values
+ if ($opcodes{$enumname})
+ {
+ }
+ elsif ($size == 1)
+ {
+ $opcodes{$enumname} = $s2;
+ }
+ elsif ($size == 2)
+ {
+ $opcodes{$enumname} = ($s2 + 256 * $s1);
+ }
+
+ #Make a list of the instructions which only take one-byte arguments
+ if ($enumname =~ /^.*_S$/) {
+ #but exclude the deprecated expressions (sometimes spelled "depricated")
+ if (!($enumname=~/^Depr.cated.*/)) {
+ my $caseStatement = sprintf(" case %-20s: \n", $enumname);
+ push(@singleByteArg, $caseStatement);
+ }
+ }
+
+ #make a list of the control Flow Types
+ if ($controlFlow{$ctrl})
+ {
+ #printf("DUPE Control Flow\n");
+ }
+ else
+ {
+ $controlFlow{$ctrl} = $ctrlflowcount;
+ $ctrlflowcount++;
+ }
+
+ $ctrlflowcount = 0;
+ #make a list of the StackBehaviour Types
+ $pop=~s/\+/_/g;
+ if ($stackbehav{$pop})
+ {
+ #printf("DUPE stack behaviour pop\n");
+ }
+ else
+ {
+ $stackbehav{$pop} = $ctrlflowcount;
+ $ctrlflowcount++;
+ }
+
+ #make a list of the StackBehaviour Types
+ $push=~s/\+/_/g;
+ if ($stackbehav{$push})
+ {
+ #printf("DUPE stack behaviour push\n");
+ }
+ else
+ {
+ $stackbehav{$push} = $ctrlflowcount;
+ $ctrlflowcount++;
+ }
+ #make a list of operand types
+ if ($operandtype{$operand})
+ {
+ #printf("DUPE operand type\n");
+ }
+ else
+ {
+ $operandtype{$operand} = $ctrlflowcount;
+ $ctrlflowcount++;
+ }
+
+
+ #make a list of opcode types
+ if ($opcodetype{$type})
+ {
+ #printf("DUPE opcode type\n");
+ }
+ else
+ {
+ $opcodetype{$type} = $ctrlflowcount;
+ $ctrlflowcount++;
+ }
+
+ my $opcodeName = $enumname;
+
+ # Tailcall OpCode enum name does not comply with convention
+ # that all enum names are exactly the same as names in opcode.def
+ # file less leading CEE_ and changed casing convention
+ $enumname = substr $enumname, 0, 4 unless $enumname !~ m/Tailcall$/;
+
+ # If string name ends with dot OpCode enum name ends with underscore
+ $enumname .= "_" unless $stringname !~ m/\."$/;
+
+ printf(" OpCode name:%20s,\t\tEnum label:%20s,\t\tString name:%20s\n", $opcodeName, $enumname, $stringname);
+ if ($stringname eq "arglist")
+ {
+ print "This is arglist----------\n";
+ }
+
+ my $lineEnum;
+ if ($size == 1)
+ {
+ $lineEnum = sprintf(" %s = 0x%.2x,\n", $enumname, $s2);
+ $opcodeEnum{$s2} = $lineEnum;
+ }
+ elsif ($size == 2)
+ {
+ $lineEnum = sprintf(" %s = 0x%.4x,\n", $enumname, $s2 + 256 * $s1);
+ $opcodeEnum{$s2 + 256 * $s1} = $lineEnum;
+ }
+
+ my $line;
+ $line = sprintf(" public static readonly OpCode %s = new OpCode(OpCodeValues.%s,\n", $opcodeName, $enumname);
+ $line .= sprintf(" ((int)OperandType.%s) |\n", $operand);
+ $line .= sprintf(" ((int)FlowControl.%s << OpCode.FlowControlShift) |\n", $ctrl);
+ $line .= sprintf(" ((int)OpCodeType.%s << OpCode.OpCodeTypeShift) |\n", $type);
+ $line .= sprintf(" ((int)StackBehaviour.%s << OpCode.StackBehaviourPopShift) |\n", $pop);
+ $line .= sprintf(" ((int)StackBehaviour.%s << OpCode.StackBehaviourPushShift) |\n", $push);
+
+ $popstate = 0;
+ if($pop eq "Pop0" || $pop eq "Varpop")
+ {
+ $popstate = 0;
+ }
+ elsif ($pop eq "Pop1" || $pop eq "Popi" || $pop eq "Popref")
+ {
+ $popstate = $popstate -1;
+ }
+ elsif ($pop eq "Pop1_pop1" || $pop eq "Popi_pop1" || $pop eq "Popi_popi" || $pop eq "Popi_popi8" || $pop eq "Popi_popr4" || $pop eq "Popi_popr8" || $pop eq "Popref_pop1" || $pop eq "Popref_popi")
+ {
+ $popstate = $popstate -2;
+ }
+ elsif ($pop eq "Popi_popi_popi" || $pop eq "Popref_popi_popi" || $pop eq "Popref_popi_popi8" || $pop eq "Popref_popi_popr4" || $pop eq "Popref_popi_popr8" || $pop eq "Popref_popi_popref" || $pop eq "Popref_popi_pop1")
+ {
+ $popstate = $popstate -3;
+ }
+
+ if ($push eq "Push1" || $push eq "Pushi" ||$push eq "Pushi8" ||$push eq "Pushr4" ||$push eq "Pushr8" ||$push eq "Pushref")
+ {
+ $popstate = $popstate + 1;
+ }
+ elsif($push eq "Push1_push1")
+ {
+ $popstate = $popstate + 2;
+ }
+
+ $line .= sprintf(" (%s << OpCode.SizeShift) |\n", $size);
+ if ($ctrl =~ m/Return/ || $ctrl =~ m/^Branch/ || $ctrl =~ m/^Throw/ || $enumname =~ m/Jmp/){
+ $line .= sprintf(" OpCode.EndsUncondJmpBlkFlag |\n", $size);
+ }
+ $line .= sprintf(" (%d << OpCode.StackChangeShift)\n", $popstate);
+ $line .= sprintf(" );\n\n");
+
+ if ($size == 1)
+ {
+ if ($oneByte{$s2})
+ {
+ printf("Error opcode 0x%x already defined!\n", $s2);
+ print " Old = $oneByte{$s2}";
+ print " New = $line";
+ $ret = -1;
+ }
+ $oneByte{$s2} = $line;
+ }
+ elsif ($size == 2)
+ {
+ if ($twoByte{$s2})
+ {
+ printf("Error opcode 0x%x%x already defined!\n", $s1, $s2);
+ print " Old = $oneByte{$s2}";
+ print " New = $line";
+ $ret = -1;
+ }
+
+ $twoByte{$s2 + 256 * $s1} = $line;
+ }
+ else
+ {
+ $line .= "\n";
+ push(@deprecated, $line);
+ printf("deprecated code!\n");
+ }
+ $count++;
+ }
+}
+
+# Generate the Flow Control enum
+$ctrlflowcount = 0;
+foreach $key (sort {$a cmp $b} keys (%controlFlow))
+{
+ print FCOUTPUT " $key";
+ print FCOUTPUT " = $ctrlflowcount,\n";
+ $ctrlflowcount++;
+ if ($key =~ m/Next/){
+ print FCOUTPUT $obsoleteAttr;
+ print FCOUTPUT " Phi";
+ print FCOUTPUT " = $ctrlflowcount,\n";
+ $ctrlflowcount++;
+ }
+}
+#end the flowcontrol enum
+print FCOUTPUT " }\n}\n";
+
+# Generate the StackBehaviour enum
+$ctrlflowcount = 0;
+foreach $key (sort {$a cmp $b} keys (%stackbehav))
+{
+ if ($key !~ m/Popref_popi_pop1/){
+ print SOUTPUT " $key";
+ print SOUTPUT " = $ctrlflowcount,\n";
+ $ctrlflowcount++;
+ }
+}
+print SOUTPUT " Popref_popi_pop1 = $ctrlflowcount,\n";
+#end the StackBehaviour enum
+print SOUTPUT " }\n}\n";
+
+# Generate OpCodeType enum
+$ctrlflowcount = 0;
+foreach $key (sort {$a cmp $b} keys (%opcodetype))
+{
+ if ($ctrlflowcount == 0){
+ print OCOUTPUT $obsoleteAttr;
+ print OCOUTPUT " Annotation = 0,\n";
+ $ctrlflowcount++;
+ }
+ print OCOUTPUT " $key";
+ print OCOUTPUT " = $ctrlflowcount,\n";
+ $ctrlflowcount++;
+}
+# end the OpCodeType enum
+print OCOUTPUT " }\n}\n";
+
+# Generate OperandType enum
+$ctrlflowcount = 0;
+foreach $key (sort {$a cmp $b} keys (%operandtype))
+{
+ print OPOUTPUT " $key";
+ print OPOUTPUT " = $ctrlflowcount,\n";
+ $ctrlflowcount++;
+ if ($key =~ m/InlineNone/){
+ print OPOUTPUT $obsoleteAttr;
+ print OPOUTPUT " InlinePhi = 6,\n";
+ $ctrlflowcount++;
+ }
+ if ($key =~ m/^InlineR$/){
+ $ctrlflowcount++;
+ }
+}
+#end the OperandType enum
+print OPOUTPUT " }\n}\n";
+
+# Generate OpCodeValues internal enum
+print OUTPUT " ///\n";
+print OUTPUT " /// Internal enum OpCodeValues for opcode values.\n";
+print OUTPUT " ///\n";
+print OUTPUT " ///\n";
+print OUTPUT " /// Note that the value names are used to construct publicly visible\n";
+print OUTPUT " /// ilasm-compatible opcode names, so their exact form is important!\n";
+print OUTPUT " ///\n";
+print OUTPUT " internal enum OpCodeValues\n";
+print OUTPUT " {\n";
+
+foreach $opcodeValue (sort {$a <=> $b} keys(%opcodeEnum)) {
+ print OUTPUT $opcodeEnum{$opcodeValue};
+}
+
+# End generating OpCodeValues internal enum
+print OUTPUT " }\n\n";
+
+
+# Generate public OpCodes class
+print OUTPUT " /// \n";
+print OUTPUT " /// \n";
+print OUTPUT " /// The IL instruction opcodes supported by the runtime.\n";
+print OUTPUT " /// The Specification of IL Instruction describes each Opcode.\n";
+print OUTPUT " /// \n";
+print OUTPUT " /// \n";
+print OUTPUT " /// \n";
+print OUTPUT " public class OpCodes\n";
+print OUTPUT " {\n\n";;
+print OUTPUT " private OpCodes()\n {\n }\n\n";
+
+my $opcode;
+my $lastOp = -1;
+foreach $opcode (sort {$a <=> $b} keys(%oneByte)) {
+ printf("***** GAP %d instrs ****\n", $opcode - $lastOp) if ($lastOp + 1 != $opcode && $lastOp > 0);
+ print OUTPUT $oneByte{$opcode};
+ $lastOp = $opcode;
+}
+
+$lastOp = -1;
+foreach $opcode (sort {$a <=> $b} keys(%twoByte)) {
+ printf("***** GAP %d instrs ****\n", $opcode - $lastOp) if ($lastOp + 1 != $opcode && $lastOp > 0);
+ print OUTPUT $twoByte{$opcode};
+ $lastOp = $opcode;
+}
+
+print OUTPUT "\n";;
+print OUTPUT " public static bool TakesSingleByteArgument(OpCode inst)\n";
+print OUTPUT " {\n";
+print OUTPUT " switch (inst.OperandType)\n";
+print OUTPUT " {\n";
+print OUTPUT " case OperandType.ShortInlineBrTarget:\n";
+print OUTPUT " case OperandType.ShortInlineI:\n";
+print OUTPUT " case OperandType.ShortInlineVar:\n";
+print OUTPUT " return true;\n";
+print OUTPUT " }\n";
+print OUTPUT " return false;\n";
+print OUTPUT " }\n";
+
+# End Generate public OpCodes class and close namespace
+print OUTPUT " }\n}\n";
+
+exit($ret);
diff --git a/lib/coreclr/src/inc/allocacheck.h b/lib/coreclr/src/inc/allocacheck.h
new file mode 100644
index 0000000000..3ba2e4da43
--- /dev/null
+++ b/lib/coreclr/src/inc/allocacheck.h
@@ -0,0 +1,84 @@
+// 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.
+/*********************************************************************/
+/* AllocaCheck */
+/*********************************************************************/
+
+/* check for alloca overruns (which otherwise are hard to track down
+ and often only repro on optimized builds).
+
+ USAGE:
+
+ void foo() {
+ ALLOCA_CHECK(); // Declare at function level scope
+
+ ....
+ void* mem = ALLOCA(size); // does an alloca,
+
+ } // destructor of ALLOCA_CHECK for buffer overruns.
+*/
+
+/* */
+/*********************************************************************/
+
+#ifndef AllocaCheck_h
+#define AllocaCheck_h
+#include // for alloca itself
+
+#if defined(assert) && !defined(_ASSERTE)
+#define _ASSERTE assert
+#endif
+
+#if defined(_DEBUG) || defined(DEBUG)
+
+/*********************************************************************/
+class AllocaCheck {
+public:
+ enum { CheckBytes = 0xCCCDCECF,
+ };
+
+ struct AllocaSentinal {
+ int check;
+ AllocaSentinal* next;
+ };
+
+public:
+ /***************************************************/
+ AllocaCheck() {
+ sentinals = 0;
+ }
+
+ ~AllocaCheck() {
+ AllocaSentinal* ptr = sentinals;
+ while (ptr != 0) {
+ if (ptr->check != (int)CheckBytes)
+ _ASSERTE(!"alloca buffer overrun");
+ ptr = ptr->next;
+ }
+ }
+
+ void* add(void* allocaBuff, unsigned size) {
+ AllocaSentinal* newSentinal = (AllocaSentinal*) ((char*) allocaBuff + size);
+ newSentinal->check = CheckBytes;
+ newSentinal->next = sentinals;
+ sentinals = newSentinal;
+ memset(allocaBuff, 0xDD, size);
+ return allocaBuff;
+ }
+
+private:
+ AllocaSentinal* sentinals;
+};
+
+#define ALLOCA_CHECK() AllocaCheck __allocaChecker
+#define ALLOCA(size) __allocaChecker.add(_alloca(size+sizeof(AllocaCheck::AllocaSentinal)), size);
+
+#else
+
+#define ALLOCA_CHECK()
+#define ALLOCA(size) _alloca(size)
+
+#endif
+
+#endif
diff --git a/lib/coreclr/src/inc/apithreadstress.cpp b/lib/coreclr/src/inc/apithreadstress.cpp
new file mode 100644
index 0000000000..0a802a2f11
--- /dev/null
+++ b/lib/coreclr/src/inc/apithreadstress.cpp
@@ -0,0 +1,171 @@
+// 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.
+
+// ---------------------------------------------------------------------------
+// APIThreadStress.cpp (API thread stresser)
+// ---------------------------------------------------------------------------
+
+#include "stdafx.h"
+
+#ifdef _DEBUG
+#define LOGGING 1
+#endif
+
+#include "apithreadstress.h"
+#include "clrhost.h"
+#include "ex.h"
+#include "log.h"
+
+
+
+// For now, thread stress is incompatible with hosting. We need a host CreateThread
+// to fix this.
+#undef SetEvent
+#undef ResetEvent
+
+int APIThreadStress::s_threadStressCount = 0;
+
+APIThreadStress::APIThreadStress()
+{
+ m_threadCount = 0;
+
+ // Don't "fork" stress threads
+ if (ClrFlsGetValue(TlsIdx_StressThread) == NULL)
+ m_threadCount = s_threadStressCount;
+
+ if (m_threadCount != 0)
+ {
+ m_setupOK = TRUE;
+
+ m_hThreadArray = new (nothrow) HANDLE [ m_threadCount ];
+ if (m_hThreadArray == NULL)
+ m_setupOK = FALSE;
+ else
+ {
+ HANDLE *p = m_hThreadArray;
+ HANDLE *pEnd = p + m_threadCount;
+
+ while (p < pEnd)
+ {
+ DWORD id;
+ *p = ::CreateThread(NULL, 0, StartThread, this, 0, &id);
+ if (*p == NULL)
+ m_setupOK = FALSE;
+ p++;
+ }
+ }
+
+ m_syncEvent = ClrCreateManualEvent(FALSE);
+ if (m_syncEvent == INVALID_HANDLE_VALUE)
+ m_setupOK = FALSE;
+ }
+}
+
+APIThreadStress::~APIThreadStress()
+{
+ if (m_threadCount > 0)
+ {
+ HANDLE *p = m_hThreadArray;
+ HANDLE *pEnd = p + m_threadCount;
+
+ if (p != NULL)
+ {
+ while (p < pEnd)
+ {
+ if (*p != NULL)
+ {
+ if (m_threadCount > 0 && m_setupOK)
+ WaitForSingleObjectEx(*p, INFINITE, FALSE);
+
+ ::CloseHandle(*p);
+ }
+ p++;
+ }
+ delete [] m_hThreadArray;
+ }
+
+ if (m_syncEvent != INVALID_HANDLE_VALUE)
+ CloseHandle(m_syncEvent);
+ }
+}
+
+void APIThreadStress::SetThreadStressCount(int threadCount)
+{
+ s_threadStressCount = threadCount;
+}
+
+
+DWORD WINAPI APIThreadStress::StartThread(void *arg)
+{
+ APIThreadStress *pThis = (APIThreadStress *) arg;
+
+ ClrFlsSetValue(TlsIdx_StressThread, pThis);
+
+ EX_TRY
+ {
+ // Perform initial synchronization
+ WaitForSingleObjectEx(pThis->m_syncEvent, INFINITE, FALSE);
+ InterlockedIncrement(&pThis->m_runCount);
+
+ LOG((LF_SYNC, LL_INFO100, "Stressing operation on thread %d\n", GetCurrentThreadId()));
+ ((APIThreadStress *)arg)->Invoke();
+ LOG((LF_SYNC, LL_INFO100, "End stress operation on thread %d\n", GetCurrentThreadId()));
+
+ if (InterlockedDecrement(&pThis->m_runCount) == 0)
+ ::SetEvent(pThis->m_syncEvent);
+ }
+ EX_CATCH
+ {
+ LOG((LF_SYNC, LL_ERROR, "Exception during stress operation on thread %d\n", GetCurrentThreadId()));
+ }
+ EX_END_CATCH(SwallowAllExceptions);
+
+ return 0;
+}
+
+BOOL APIThreadStress::DoThreadStress()
+{
+ if (m_threadCount > 0 && m_setupOK)
+ {
+ HANDLE *p = m_hThreadArray;
+ HANDLE *pEnd = p + m_threadCount;
+
+ while (p < pEnd)
+ {
+ ::ResumeThread(*p);
+ p++;
+ }
+
+ // Start the threads at the same time
+ ::SetEvent(m_syncEvent);
+
+ return TRUE;
+ }
+ else
+ {
+ SyncThreadStress();
+ return FALSE;
+ }
+}
+
+void APIThreadStress::SyncThreadStress()
+{
+ APIThreadStress *pThis = (APIThreadStress *) ClrFlsGetValue(TlsIdx_StressThread);
+
+ if (pThis != NULL)
+ {
+ LOG((LF_SYNC, LL_INFO1000, "Syncing stress operation on thread %d\n", GetCurrentThreadId()));
+
+ ::ResetEvent(pThis->m_syncEvent);
+
+ if (InterlockedDecrement(&pThis->m_runCount) == 0)
+ ::SetEvent(pThis->m_syncEvent);
+ else
+ WaitForSingleObjectEx(pThis->m_syncEvent, INFINITE, FALSE);
+ InterlockedIncrement(&pThis->m_runCount);
+
+ LOG((LF_SYNC, LL_INFO1000, "Resuming stress operation on thread %d\n", GetCurrentThreadId()));
+ }
+}
+
diff --git a/lib/coreclr/src/inc/apithreadstress.h b/lib/coreclr/src/inc/apithreadstress.h
new file mode 100644
index 0000000000..a0c6cdeb0b
--- /dev/null
+++ b/lib/coreclr/src/inc/apithreadstress.h
@@ -0,0 +1,57 @@
+// 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.
+// ---------------------------------------------------------------------------
+// APIThreadStress.h (API thread stresser)
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+// This class provides a simple base to wrap "thread stress" logic around an API,
+// which will (in thread stress mode) cause an API to "fork" onto many threads
+// executing the same operation simulatenously. This can help to expose race
+// conditions.
+//
+// Usage:
+//
+// First, subtype APIThreadStress and override Invoke to implement the operation.
+// You will likely need to add data members for the arguments.
+//
+// Next, inside the API, write code like this:
+//
+// void MyRoutine(int a1, void *a2)
+// {
+// class stress : APIThreadStress
+// {
+// int a1;
+// void *a2;
+// stress(int a1, void *a2) : a1(a1), a2(a2)
+// { DoThreadStress(); }
+// void Invoke() { MyRoutine(a1, a2); }
+// } ts (a1, a2);
+//
+// // implementation
+//
+// // perhaps we have a common sub-point in the routine where we want the threads to
+// // queue up and race again
+//
+// ts.SyncThreadStress();
+//
+// // more implementation
+// }
+// ---------------------------------------------------------------------------
+
+
+#ifndef _APITHREADSTRESS_H_
+#define _APITHREADSTRESS_H_
+
+#include "utilcode.h"
+
+class APIThreadStress
+{
+ public:
+ BOOL DoThreadStress() { return FALSE; }
+ static void SyncThreadStress() { }
+ static void SetThreadStressCount(int count) { }
+};
+
+#endif // _APITHREADSTRESS_H_
diff --git a/lib/coreclr/src/inc/appxutil.h b/lib/coreclr/src/inc/appxutil.h
new file mode 100644
index 0000000000..411c18b695
--- /dev/null
+++ b/lib/coreclr/src/inc/appxutil.h
@@ -0,0 +1,51 @@
+// 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.
+//
+
+
+#pragma once
+
+#ifdef FEATURE_APPX
+
+#include "clrtypes.h"
+#include "appmodel.h"
+
+#define PACKAGE_FILTER_CLR_DEFAULT (PACKAGE_FILTER_HEAD|PACKAGE_FILTER_DIRECT)
+
+
+typedef PACKAGE_INFO * PPACKAGE_INFO;
+typedef PACKAGE_INFO const * PCPACKAGE_INFO;
+
+//---------------------------------------------------------------------------------------------
+// Forward declarations
+template
+class NewArrayHolder;
+BOOL WinRTSupported();
+
+
+namespace AppX
+{
+ // Returns true if process is immersive (or if running in mockup environment).
+ bool IsAppXProcess();
+
+ // On CoreCLR, the host is in charge of determining whether the process is AppX or not.
+ void SetIsAppXProcess(bool);
+
+#ifdef DACCESS_COMPILE
+ bool DacIsAppXProcess();
+#endif // DACCESS_COMPILE
+};
+
+
+#else // FEATURE_APPX
+
+namespace AppX
+{
+ inline bool IsAppXProcess()
+ {
+ return false;
+ }
+}
+
+#endif // FEATURE_APPX
diff --git a/lib/coreclr/src/inc/arrayholder.h b/lib/coreclr/src/inc/arrayholder.h
new file mode 100644
index 0000000000..681014fc95
--- /dev/null
+++ b/lib/coreclr/src/inc/arrayholder.h
@@ -0,0 +1,80 @@
+// 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.
+
+template
+class ArrayHolder
+{
+public:
+ ArrayHolder(T *ptr)
+ : m_ptr(ptr)
+ {
+ }
+
+ ~ArrayHolder()
+ {
+ Clear();
+ }
+
+ ArrayHolder(const ArrayHolder &rhs)
+ {
+ m_ptr = const_cast(&rhs)->Detach();
+ }
+
+ ArrayHolder &operator=(T *ptr)
+ {
+ Clear();
+ m_ptr = ptr;
+ return *this;
+ }
+
+ const T &operator[](int i) const
+ {
+ return m_ptr[i];
+ }
+
+ T &operator[](int i)
+ {
+ return m_ptr[i];
+ }
+
+ operator const T *() const
+ {
+ return m_ptr;
+ }
+
+ operator T *()
+ {
+ return m_ptr;
+ }
+
+ T **operator&()
+ {
+ return &m_ptr;
+ }
+
+ T *GetPtr()
+ {
+ return m_ptr;
+ }
+
+ T *Detach()
+ {
+ T *ret = m_ptr;
+ m_ptr = NULL;
+ return ret;
+ }
+
+private:
+ void Clear()
+ {
+ if (m_ptr)
+ {
+ delete [] m_ptr;
+ m_ptr = NULL;
+ }
+ }
+
+private:
+ T *m_ptr;
+};
diff --git a/lib/coreclr/src/inc/arraylist.h b/lib/coreclr/src/inc/arraylist.h
new file mode 100644
index 0000000000..b8c149f8eb
--- /dev/null
+++ b/lib/coreclr/src/inc/arraylist.h
@@ -0,0 +1,296 @@
+// 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.
+
+
+#ifndef ARRAYLIST_H_
+#define ARRAYLIST_H_
+
+#include
+#include
+#include // offsetof
+
+//
+// ArrayList is a simple class which is used to contain a growable
+// list of pointers, stored in chunks. Modification is by appending
+// only currently. Access is by index (efficient if the number of
+// elements stays small) and iteration (efficient in all cases).
+//
+// An important property of an ArrayList is that the list remains
+// coherent while it is being modified. This means that readers
+// never need to lock when accessing it.
+//
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4200) // Disable zero-sized array warning
+#endif
+
+class ArrayListBase
+{
+ public:
+
+ enum
+ {
+ ARRAY_BLOCK_SIZE_START = 5,
+ };
+
+ private:
+
+ struct ArrayListBlock
+ {
+ SPTR(ArrayListBlock) m_next;
+ DWORD m_blockSize;
+#ifdef _WIN64
+ DWORD m_padding;
+#endif
+ PTR_VOID m_array[0];
+
+#ifdef DACCESS_COMPILE
+ static ULONG32 DacSize(TADDR addr)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return offsetof(ArrayListBlock, m_array) +
+ (*PTR_DWORD(addr + offsetof(ArrayListBlock, m_blockSize)) * sizeof(void*));
+ }
+#endif
+ };
+ typedef SPTR(ArrayListBlock) PTR_ArrayListBlock;
+
+ struct FirstArrayListBlock
+ {
+ PTR_ArrayListBlock m_next;
+ DWORD m_blockSize;
+#ifdef _WIN64
+ DWORD m_padding;
+#endif
+ void * m_array[ARRAY_BLOCK_SIZE_START];
+ };
+
+ typedef DPTR(FirstArrayListBlock) PTR_FirstArrayListBlock;
+
+ DWORD m_count;
+ FirstArrayListBlock m_firstBlock;
+
+ public:
+
+ PTR_VOID *GetPtr(DWORD index) const;
+ PTR_VOID Get(DWORD index) const
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ return *GetPtr(index);
+ }
+
+ void Set(DWORD index, PTR_VOID element)
+ {
+ WRAPPER_NO_CONTRACT;
+ *GetPtr(index) = element;
+ }
+
+ DWORD GetCount() const { LIMITED_METHOD_DAC_CONTRACT; return m_count; }
+
+ HRESULT Append(void *element);
+
+ enum { NOT_FOUND = -1 };
+ DWORD FindElement(DWORD start, PTR_VOID element) const;
+
+ void Clear();
+
+ void Init()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ m_count = 0;
+ m_firstBlock.m_next = NULL;
+ m_firstBlock.m_blockSize = ARRAY_BLOCK_SIZE_START;
+ }
+
+ void Destroy()
+ {
+ WRAPPER_NO_CONTRACT;
+ Clear();
+ }
+
+#ifdef DACCESS_COMPILE
+ void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
+#endif
+
+ class ConstIterator;
+
+ class Iterator
+ {
+ friend class ArrayListBase;
+ friend class ConstIterator;
+
+ public:
+ BOOL Next();
+
+ void SetEmpty()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ m_block = NULL;
+ m_index = (DWORD)-1;
+ m_remaining = 0;
+ m_total = 0;
+ }
+
+ PTR_VOID GetElement() {LIMITED_METHOD_DAC_CONTRACT; return m_block->m_array[m_index]; }
+ PTR_VOID * GetElementPtr() {LIMITED_METHOD_CONTRACT; return m_block->m_array + m_index; }
+ DWORD GetIndex() {LIMITED_METHOD_CONTRACT; return m_index + m_total; }
+ void *GetBlock() { return m_block; }
+
+ private:
+ ArrayListBlock* m_block;
+ DWORD m_index;
+ DWORD m_remaining;
+ DWORD m_total;
+ static Iterator Create(ArrayListBlock* block, DWORD remaining)
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ Iterator i;
+ i.m_block = block;
+ i.m_index = (DWORD) -1;
+ i.m_remaining = remaining;
+ i.m_total = 0;
+ return i;
+ }
+ };
+
+ class ConstIterator
+ {
+ public:
+ ConstIterator(ArrayListBlock *pBlock, DWORD dwRemaining) : m_iterator(Iterator::Create(pBlock, dwRemaining))
+ {
+ }
+
+ BOOL Next()
+ {
+ WRAPPER_NO_CONTRACT;
+ return m_iterator.Next();
+ }
+
+ PTR_VOID GetElement()
+ {
+ WRAPPER_NO_CONTRACT;
+ return m_iterator.GetElement();
+ }
+
+ private:
+ Iterator m_iterator;
+ };
+
+ Iterator Iterate()
+ {
+ WRAPPER_NO_CONTRACT;
+ return Iterator::Create((ArrayListBlock*)&m_firstBlock, m_count);
+ }
+
+ ConstIterator Iterate() const
+ {
+ // Const cast is safe because ConstIterator does not expose any way to modify the block
+ ArrayListBlock *pFirstBlock = const_cast(reinterpret_cast(&m_firstBlock));
+ return ConstIterator(pFirstBlock, m_count);
+ }
+
+ // BlockIterator is used for only memory walking, such as prejit save/fixup.
+ // It is not appropriate for other more typical ArrayList use.
+ class BlockIterator
+ {
+ private:
+
+ ArrayListBlock *m_block;
+ DWORD m_remaining;
+
+ friend class ArrayListBase;
+ BlockIterator(ArrayListBlock *block, DWORD remaining)
+ : m_block(block), m_remaining(remaining)
+ {
+ }
+
+ public:
+
+ BOOL Next()
+ {
+ if (m_block != NULL)
+ {
+ // Prevent m_remaining from underflowing - we can have completely empty block at the end.
+ if (m_remaining > m_block->m_blockSize)
+ m_remaining -= m_block->m_blockSize;
+ else
+ m_remaining = 0;
+
+ m_block = m_block->m_next;
+ }
+ return m_block != NULL;
+ }
+
+ void ClearUnusedMemory()
+ {
+ if (m_remaining < m_block->m_blockSize)
+ ZeroMemory(&(m_block->m_array[m_remaining]), (m_block->m_blockSize - m_remaining) * sizeof(void*));
+#ifdef _WIN64
+ m_block->m_padding = 0;
+#endif
+ }
+
+ void **GetNextPtr()
+ {
+ return (void **) &m_block->m_next;
+ }
+
+ void *GetBlock()
+ {
+ return m_block;
+ }
+
+ SIZE_T GetBlockSize()
+ {
+ return offsetof(ArrayListBlock, m_array) + (m_block->m_blockSize * sizeof(void*));
+ }
+ };
+
+ void **GetInitialNextPtr()
+ {
+ return (void **) &m_firstBlock.m_next;
+ }
+
+ BlockIterator IterateBlocks()
+ {
+ return BlockIterator((ArrayListBlock *) &m_firstBlock, m_count);
+ }
+
+};
+
+class ArrayList : public ArrayListBase
+{
+public:
+#ifndef DACCESS_COMPILE
+ ArrayList()
+ {
+ WRAPPER_NO_CONTRACT;
+ Init();
+ }
+
+ ~ArrayList()
+ {
+ WRAPPER_NO_CONTRACT;
+ Destroy();
+ }
+#endif
+};
+
+/* to be used as static variable - no constructor/destructor, assumes zero
+ initialized memory */
+class ArrayListStatic : public ArrayListBase
+{
+};
+
+typedef DPTR(ArrayListStatic) PTR_ArrayListStatic;
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/lib/coreclr/src/inc/bbsweep.h b/lib/coreclr/src/inc/bbsweep.h
new file mode 100644
index 0000000000..d5526d8e5c
--- /dev/null
+++ b/lib/coreclr/src/inc/bbsweep.h
@@ -0,0 +1,425 @@
+// 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.
+
+/*****************************************************************************\
+* *
+* BBSweep.h - Classes for sweeping profile data to disk *
+* *
+* Version 1.0 *
+*******************************************************************************
+* *
+* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY *
+* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR *
+* PURPOSE. *
+* *
+\*****************************************************************************/
+
+#ifndef _BBSWEEP_H_
+#define _BBSWEEP_H_
+
+#ifndef FEATURE_PAL
+#include
+#endif // !FEATURE_PAL
+
+// The CLR headers don't allow us to use methods like SetEvent directly (instead
+// we need to use the host APIs). However, this file is included both in the CLR
+// and in the BBSweep tool, and the host API is not available in the tool. Moreover,
+// BBSweep is not designed to work in an environment where the host controls
+// synchronization. For this reason, we work around the problem by undefining
+// these APIs (the CLR redefines them so that they will not be used).
+#pragma push_macro("SetEvent")
+#pragma push_macro("ResetEvent")
+#pragma push_macro("ReleaseSemaphore")
+#pragma push_macro("LocalFree")
+#undef SetEvent
+#undef ResetEvent
+#undef ReleaseSemaphore
+#undef LocalFree
+
+// MAX_COUNT is the maximal number of runtime processes that can run at a given time
+#define MAX_COUNT 20
+
+#define INVALID_PID -1
+
+/* CLRBBSweepCallback is implemented by the CLR which passes it as an argument to WatchForSweepEvents.
+ * It is used by BBSweep to tell the CLR to write the profile data to disk at the right time.
+ */
+
+class ICLRBBSweepCallback
+{
+public:
+ virtual HRESULT WriteProfileData() = NULL; // tells the runtime to write the profile data to disk
+};
+
+/* BBSweep is used by both the CLR and the BBSweep utility.
+ * BBSweep: calls the PerformSweep method which returns after all the CLR processes
+ * have written their profile data to disk.
+ * CLR: starts up a sweeper thread which calls WatchForSweepEvents and waits until the
+ * sweeper program is invoked. At that point, all the CLR processes will synchronize
+ * and write their profile data to disk one at a time. The sweeper threads will then
+ * wait for the next sweep event. The CLR also calls ShutdownBBSweepThread at
+ * shutdown which returns when the BBSweep thread has terminated.
+ */
+
+class BBSweep
+{
+public:
+ BBSweep()
+ {
+ // The BBSweep constructor could be called even the the object is not used, so
+ // don't do any work here.
+ bInitialized = false;
+ bTerminate = false;
+ hSweepMutex = NULL;
+ hProfDataWriterMutex = NULL;
+ hSweepEvent = NULL;
+ hTerminationEvent = NULL;
+ hProfWriterSemaphore = NULL;
+ hBBSweepThread = NULL;
+ }
+
+ ~BBSweep()
+ {
+ // When the destructor is called, everything should be cleaned up already.
+ }
+
+ // Called by the sweeper utility to tell all the CLR threads to write their profile
+ // data to disk.
+ // THIS FUNCTIONALITY IS ALSO DUPLICATED IN TOOLBOX\MPGO\BBSWEEP.CS
+ // IF YOU CHANGE THIS CODE, YOU MUST ALSO CHANGE THAT TO MATCH!
+ bool PerformSweep(DWORD processID = INVALID_PID)
+ {
+ bool success = true;
+
+ if (!Initialize(processID, FALSE)) return false;
+
+ ::WaitForSingleObject(hSweepMutex, INFINITE);
+ {
+ success = success && ::SetEvent(hSweepEvent);
+ {
+ for (int i=0; iWriteProfileData()))
+ success = false;
+ }
+ ::ReleaseMutex(hProfDataWriterMutex);
+
+ ::ReleaseSemaphore(hProfWriterSemaphore, 1, NULL);
+ }
+
+ return success;
+ }
+
+ void SetBBSweepThreadHandle(HANDLE threadHandle)
+ {
+ hBBSweepThread = threadHandle;
+ }
+
+ void ShutdownBBSweepThread()
+ {
+ // Set the termination event and wait for the BBSweep thread to terminate on its own.
+ // Note that this is called by the shutdown thread (and never called by the BBSweep thread).
+ if (hBBSweepThread && bInitialized)
+ {
+ bTerminate = true;
+ ::SetEvent(hTerminationEvent);
+ ::WaitForSingleObject(hBBSweepThread, INFINITE);
+ Cleanup();
+ }
+ }
+
+ void Cleanup()
+ {
+ if (hSweepMutex) { ::CloseHandle(hSweepMutex); hSweepMutex = NULL;}
+ if (hProfDataWriterMutex) { ::CloseHandle(hProfDataWriterMutex); hProfDataWriterMutex = NULL;}
+ if (hSweepEvent) { ::CloseHandle(hSweepEvent); hSweepEvent = NULL;}
+ if (hTerminationEvent) { ::CloseHandle(hTerminationEvent); hTerminationEvent = NULL;}
+ if (hProfWriterSemaphore) { ::CloseHandle(hProfWriterSemaphore); hProfWriterSemaphore = NULL;}
+ }
+
+private:
+
+ // THIS FUNCTIONALITY IS ALSO DUPLICATED IN TOOLBOX\MPGO\BBSWEEP.CS
+ // IF YOU CHANGE THIS CODE, YOU MUST ALSO CHANGE THAT TO MATCH!
+ bool Initialize(DWORD processID = INVALID_PID, BOOL fromRuntime = TRUE)
+ {
+ if (!bInitialized)
+ {
+ SECURITY_ATTRIBUTES * pSecurityAttributes = NULL;
+
+#ifndef FEATURE_CORESYSTEM // @CORESYSTEMTODO
+ PSECURITY_DESCRIPTOR pSD = NULL;
+ PSID pAdminSid = NULL;
+ HANDLE hToken = NULL;
+ PACL pACL = NULL;
+ LPVOID buffer = NULL;
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
+ goto cleanup;
+
+ // don't set pSecurityAttributes for Metro processes
+ if(!IsAppContainerProcess(hToken))
+ {
+ SECURITY_ATTRIBUTES securityAttributes;
+ PSID pUserSid = NULL;
+ SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
+ DWORD retLength;
+
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:6211) // PREfast warning: Leaking memory 'pSD' due to an exception.
+#endif /*_PREFAST_ */
+ pSD = (PSECURITY_DESCRIPTOR) new char[SECURITY_DESCRIPTOR_MIN_LENGTH];
+ if (!pSD)
+ goto cleanup;
+
+ if (GetTokenInformation(hToken, TokenOwner, NULL, 0, &retLength))
+ goto cleanup;
+
+ buffer = (LPVOID) new char[retLength];
+ if (!buffer)
+ goto cleanup;
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif /*_PREFAST_*/
+
+ // Get the SID for the current user
+ if (!GetTokenInformation(hToken, TokenOwner, (LPVOID) buffer, retLength, &retLength))
+ goto cleanup;
+
+ pUserSid = ((TOKEN_OWNER *) buffer)->Owner;
+
+ // Get the SID for the admin group
+ // Create a SID for the BUILTIN\Administrators group.
+ if(! AllocateAndInitializeSid(&SIDAuthNT, 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &pAdminSid))
+ goto cleanup;
+
+ EXPLICIT_ACCESS ea[2];
+ ZeroMemory(ea, 2 * sizeof(EXPLICIT_ACCESS));
+
+ // Initialize an EXPLICIT_ACCESS structure for an ACE.
+ // The ACE will allow the current user full access
+ ea[0].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; // KEY_ALL_ACCESS;
+ ea[0].grfAccessMode = SET_ACCESS;
+ ea[0].grfInheritance= NO_INHERITANCE;
+ ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
+ ea[0].Trustee.ptstrName = (LPTSTR) pUserSid;
+
+ // Initialize an EXPLICIT_ACCESS structure for an ACE.
+ // The ACE will allow admins full access
+ ea[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; //KEY_ALL_ACCESS;
+ ea[1].grfAccessMode = SET_ACCESS;
+ ea[1].grfInheritance= NO_INHERITANCE;
+ ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
+ ea[1].Trustee.ptstrName = (LPTSTR) pAdminSid;
+
+ if (SetEntriesInAcl(2, ea, NULL, &pACL) != ERROR_SUCCESS)
+ goto cleanup;
+
+ if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
+ goto cleanup;
+
+ if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE))
+ goto cleanup;
+
+ memset((void *) &securityAttributes, 0, sizeof(SECURITY_ATTRIBUTES));
+ securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ securityAttributes.lpSecurityDescriptor = pSD;
+ securityAttributes.bInheritHandle = FALSE;
+
+ pSecurityAttributes = &securityAttributes;
+ }
+#endif // !FEATURE_CORESYSTEM
+
+ WCHAR objectName[MAX_LONGPATH] = {0};
+ WCHAR objectNamePrefix[MAX_LONGPATH] = {0};
+ GetObjectNamePrefix(processID, fromRuntime, objectNamePrefix);
+ // if there is a non-empty name prefix, append a '\'
+ if (objectNamePrefix[0] != '\0')
+ wcscat_s(objectNamePrefix, ARRAYSIZE(objectNamePrefix), W("\\"));
+ swprintf_s(objectName, MAX_LONGPATH, W("%sBBSweep_hSweepMutex"), objectNamePrefix);
+ hSweepMutex = ::WszCreateMutex(pSecurityAttributes, false, objectName);
+ swprintf_s(objectName, MAX_LONGPATH, W("%sBBSweep_hProfDataWriterMutex"), objectNamePrefix);
+ hProfDataWriterMutex = ::WszCreateMutex(pSecurityAttributes, false, objectName);
+ swprintf_s(objectName, MAX_LONGPATH, W("%sBBSweep_hSweepEvent"), objectNamePrefix);
+ hSweepEvent = ::WszCreateEvent(pSecurityAttributes, true, false, objectName);
+
+ // Note that hTerminateEvent is not a named event. That is because it is not
+ // shared amongst the CLR processes (each process terminates at a different time)
+ hTerminationEvent = ::WszCreateEvent(pSecurityAttributes, true, false, NULL);
+ swprintf_s(objectName, MAX_LONGPATH, W("%sBBSweep_hProfWriterSemaphore"), objectNamePrefix);
+ hProfWriterSemaphore = ::WszCreateSemaphore(pSecurityAttributes, MAX_COUNT, MAX_COUNT, objectName);
+
+#ifndef FEATURE_CORESYSTEM // @CORESYSTEMTODO
+cleanup:
+ if (pSD) delete [] ((char *) pSD);
+ if (pAdminSid) FreeSid(pAdminSid);
+ if (hToken) CloseHandle(hToken);
+ if (pACL) LocalFree(pACL);
+ if (buffer) delete [] ((char *) buffer);
+#endif
+ }
+
+ bInitialized = hSweepMutex &&
+ hProfDataWriterMutex &&
+ hSweepEvent &&
+ hTerminationEvent &&
+ hProfWriterSemaphore;
+
+ if (!bInitialized) Cleanup();
+ return bInitialized;
+ }
+
+#ifndef FEATURE_PAL
+ BOOL IsAppContainerProcess(HANDLE hToken)
+ {
+#ifndef TokenIsAppContainer
+#define TokenIsAppContainer ((TOKEN_INFORMATION_CLASS) 29)
+#endif
+ BOOL fIsAppContainerProcess;
+ DWORD dwReturnLength;
+ if (!GetTokenInformation(hToken, TokenIsAppContainer, &fIsAppContainerProcess, sizeof(BOOL), &dwReturnLength) ||
+ dwReturnLength != sizeof(BOOL))
+ {
+ fIsAppContainerProcess = FALSE;
+ }
+ return fIsAppContainerProcess;
+ }
+#endif // !FEATURE_PAL
+
+ // helper to get the correct object name prefix
+ void GetObjectNamePrefix(DWORD processID, BOOL fromRuntime, __inout_z WCHAR* objectNamePrefix)
+ {
+ // default prefix
+ swprintf_s(objectNamePrefix, MAX_LONGPATH, W("Global"));
+#ifndef FEATURE_PAL
+ //
+ // This method can be called:
+ // 1. From process init code
+ // 2. From bbsweepclr.exe
+ //
+ // When called from process init code, processID is always INVALID_PID.
+ // In case it is a Win8-Metro/WP8 process, we need to add the AppContainerNamedObjectPath to prefix.
+ // And if it is a non-Metro process, we will continue to use the default prefix (Global).
+ // We use IsAppContainerProcess(CurrentProcessId) to make this decision.
+ //
+ //
+ // When called from bbsweepclr, processID is valid when sweeping a Metro or WP8 process.
+ // We use this valid processID to determine if the process being swept is Metro/WP8 indeed and then
+ // add AppContainerNamedObjectPath to prefix. This is done by IsAppContainerProcess(processID).
+ //
+ // In case INVALID_PID is passed(non-Metro process), we have to use default prefix. To handle this
+ // case we use IsAppContainerProcess(CurrentProcessId) and since bbsweepclr is a non-Metro process,
+ // this check always returns false and we end up using the intended(default) prefix.
+ //
+ if(processID == INVALID_PID) {
+ // we reach here when:
+ // * called from process init code:
+ // * called from bbsweepclr.exe and no processID has been passed as argument, that is, when sweeping a non-Metro process
+ processID = GetCurrentProcessId();
+ }
+
+ HandleHolder hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processID);
+ if (hProcess != INVALID_HANDLE_VALUE)
+ {
+ HandleHolder hToken = NULL;
+ // if in the process init code of a Metro app or if bbsweepclr is used to sweep a Metro app,
+ // construct the object name prefix using AppContainerNamedObjectPath
+ if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken) && IsAppContainerProcess(hToken))
+ {
+ WCHAR appxNamedObjPath[MAX_LONGPATH] = { 0 };
+ ULONG appxNamedObjPathBufLen = 0;
+
+ if (fromRuntime)
+ {
+ // for Metro apps, create the object in the "default" object path, i.e. do not provide any prefix
+ objectNamePrefix[0] = W('\0');
+ }
+ else
+ {
+#if defined (FEATURE_CORESYSTEM) && !defined(CROSSGEN_COMPILE) && !defined(DACCESS_COMPILE)
+#define MODULE_NAME W("api-ms-win-security-appcontainer-l1-1-0.dll")
+#else
+#define MODULE_NAME W("kernel32.dll")
+#endif
+ typedef BOOL(WINAPI *PFN_GetAppContainerNamedObjectPath)
+ (HANDLE Token, PSID AppContainerSid, ULONG ObjectPathLength, WCHAR * ObjectPath, PULONG ReturnLength);
+
+ PFN_GetAppContainerNamedObjectPath pfnGetAppContainerNamedObjectPath = (PFN_GetAppContainerNamedObjectPath)
+ GetProcAddress(WszGetModuleHandle(MODULE_NAME), "GetAppContainerNamedObjectPath");
+ if (pfnGetAppContainerNamedObjectPath)
+ {
+ // for bbsweepclr sweeping a Metro app, create the object specifying the AppContainer's path
+ DWORD sessionId = 0;
+ ProcessIdToSessionId(processID, &sessionId);
+ pfnGetAppContainerNamedObjectPath(hToken, NULL, sizeof (appxNamedObjPath) / sizeof (WCHAR), appxNamedObjPath, &appxNamedObjPathBufLen);
+ swprintf_s(objectNamePrefix, MAX_LONGPATH, W("Global\\Session\\%d\\%s"), sessionId, appxNamedObjPath);
+ }
+ }
+ }
+ }
+#endif // FEATURE_PAL
+ }
+private:
+
+ bool bInitialized; // true when the BBSweep object has initialized successfully
+ bool bTerminate; // set to true when the CLR wants us to terminate
+ HANDLE hSweepMutex; // prevents processing from incrementing the semaphore after the sweep has began
+ HANDLE hProfDataWriterMutex; // guarantees that profile data will be written by one process at a time
+ HANDLE hSweepEvent; // tells the CLR processes to sweep their profile data
+ HANDLE hTerminationEvent; // set when the CLR process is ready to terminate
+ HANDLE hProfWriterSemaphore; // helps determine when all the writers are finished
+ HANDLE hBBSweepThread; // a handle to the CLR sweeper thread (that calls watch for sweep events)
+};
+
+#pragma pop_macro("LocalFree")
+#pragma pop_macro("ReleaseSemaphore")
+#pragma pop_macro("ResetEvent")
+#pragma pop_macro("SetEvent")
+
+#endif //_BBSWEEP_H
diff --git a/lib/coreclr/src/inc/bitmask.h b/lib/coreclr/src/inc/bitmask.h
new file mode 100644
index 0000000000..a59d2e252d
--- /dev/null
+++ b/lib/coreclr/src/inc/bitmask.h
@@ -0,0 +1,103 @@
+// 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.
+
+//
+
+// --------------------------------------------------------------------------------
+// BitMask.h
+// --------------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------------
+// BitMask is an arbitrarily large sized bitfield which has optimal storage
+// for 32 bits or less.
+// Storage is proportional to the highest index which is set.
+// --------------------------------------------------------------------------------
+
+
+#include
+
+#ifndef _BITMASK_H_
+#define _BITMASK_H_
+
+class BitMask
+{
+ public:
+
+ BitMask();
+ ~BitMask();
+
+ BOOL TestBit(int bit);
+ void SetBit(int bit);
+ void ClearBit(int bit);
+
+ // returns true if any bit is set
+ BOOL TestAnyBit();
+
+ void ClearAllBits();
+
+ // Allocation exposed for ngen save/fixup
+ size_t GetAllocatedBlockOffset();
+ void *GetAllocatedBlock();
+ COUNT_T GetAllocatedBlockSize();
+
+ private:
+
+ static const int BIT_SIZE_SHIFT = 5;
+ static const int BIT_SIZE = (1<writer so be very careful
+ // when taking this lock else you might deadlock your own thread!
+ SimpleRWLock m_bitMaskLock;
+};
+
+#include
+
+#endif // _BITMASK_H_
diff --git a/lib/coreclr/src/inc/bitmask.inl b/lib/coreclr/src/inc/bitmask.inl
new file mode 100644
index 0000000000..00bfe0138e
--- /dev/null
+++ b/lib/coreclr/src/inc/bitmask.inl
@@ -0,0 +1,292 @@
+// 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.
+
+//
+
+// --------------------------------------------------------------------------------
+// BitMask.inl
+// --------------------------------------------------------------------------------
+
+#include
+
+#ifndef _BITMASK_INL_
+#define _BITMASK_INL_
+
+inline BOOL BitMask::IsArray()
+{
+ LIMITED_METHOD_CONTRACT;
+ return (m_mask&1) == 0;
+}
+
+// Indexing computations
+inline COUNT_T BitMask::BitToIndex(int bit)
+{
+ LIMITED_METHOD_CONTRACT;
+ // First word has one less bit due to tag
+ return (bit+1) >> BIT_SIZE_SHIFT;
+}
+
+inline COUNT_T BitMask::BitToShift(int bit)
+{
+ LIMITED_METHOD_CONTRACT;
+ // First word has one less bit due to tag
+ return (bit+1) & BIT_SIZE_MASK;
+}
+
+// Array access. Note the first array element is the count of the
+// rest of the elements
+
+inline COUNT_T *BitMask::GetMaskArray()
+{
+ LIMITED_METHOD_CONTRACT;
+ if (IsArray())
+ {
+ CONSISTENCY_CHECK(CheckPointer(m_maskArray));
+ return m_maskArray+1;
+ }
+ else
+ return &m_mask;
+}
+
+inline COUNT_T BitMask::GetMaskArraySize()
+{
+ LIMITED_METHOD_CONTRACT;
+ if (IsArray())
+ return *m_maskArray;
+ else
+ return 1;
+}
+
+inline void BitMask::GrowArray(COUNT_T newSize)
+{
+ CONTRACTL
+ {
+ THROWS;
+ }
+ CONTRACTL_END;
+
+ // Ensure we don't grow too often
+
+ COUNT_T oldSize = GetMaskArraySize();
+ if (newSize <= oldSize)
+ return;
+
+ if (newSize < oldSize*2)
+ newSize = oldSize*2;
+ if (newSize < MIN_ARRAY_ALLOCATION)
+ newSize = MIN_ARRAY_ALLOCATION;
+
+ // Allocate new array
+
+ COUNT_T *newArray = new COUNT_T [newSize+1];
+ *newArray = newSize;
+
+ CopyMemory(newArray+1, GetMaskArray(), oldSize * sizeof(COUNT_T));
+ ZeroMemory(newArray+oldSize+1, (newSize - oldSize) * sizeof(COUNT_T));
+
+ if (IsArray())
+ delete [] m_maskArray;
+
+ m_maskArray = newArray;
+}
+
+inline BitMask::BitMask()
+ : m_mask(1)
+{
+ LIMITED_METHOD_CONTRACT;
+}
+
+inline BitMask::~BitMask()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ if (IsArray())
+ delete [] m_maskArray;
+}
+
+inline BOOL BitMask::TestBit(int bit)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ COUNT_T index = BitToIndex(bit);
+
+ if (index >= GetMaskArraySize())
+ return FALSE;
+
+ return ( GetMaskArray()[index] >> BitToShift(bit) ) & 1;
+}
+
+inline void BitMask::SetBit(int bit)
+{
+ CONTRACTL
+ {
+ THROWS;
+ }
+ CONTRACTL_END;
+
+ COUNT_T index = BitToIndex(bit);
+
+ if (index >= GetMaskArraySize())
+ GrowArray(index+1);
+
+ GetMaskArray()[index] |= (1 << BitToShift(bit));
+}
+
+inline void BitMask::ClearBit(int bit)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ COUNT_T index = BitToIndex(bit);
+
+ if (index >= GetMaskArraySize())
+ return;
+
+ GetMaskArray()[index] &= ~(1 << BitToShift(bit));
+}
+
+inline BOOL BitMask::TestAnyBit()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ if (IsArray())
+ {
+ COUNT_T *mask = m_maskArray+1;
+ COUNT_T *maskEnd = mask + m_maskArray[0];
+
+ while (mask < maskEnd)
+ {
+ if (*mask != 0)
+ return TRUE;
+ mask++;
+ }
+
+ return FALSE;
+ }
+ else
+ return m_mask != (COUNT_T) 1;
+}
+
+inline void BitMask::ClearAllBits()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ if (IsArray())
+ delete [] m_maskArray;
+
+ m_mask = 1;
+}
+
+inline size_t BitMask::GetAllocatedBlockOffset()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return offsetof(BitMask, m_maskArray);
+}
+
+inline void *BitMask::GetAllocatedBlock()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ if (IsArray())
+ return m_maskArray;
+ else
+ return NULL;
+}
+
+inline COUNT_T BitMask::GetAllocatedBlockSize()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ if (IsArray())
+ return (GetMaskArraySize()+1) * sizeof(COUNT_T);
+ else
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+inline SynchronizedBitMask::SynchronizedBitMask()
+ : m_bitMaskLock(PREEMPTIVE, LOCK_TYPE_DEFAULT)
+{
+ LIMITED_METHOD_CONTRACT;
+}
+
+inline BOOL SynchronizedBitMask::TestBit(int bit)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ MODE_ANY;
+ CAN_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ SimpleReadLockHolder holder(&m_bitMaskLock);
+
+ return m_bitMask.TestBit(bit);
+}
+
+inline void SynchronizedBitMask::SetBit(int bit)
+{
+ CONTRACTL
+ {
+ THROWS;
+ MODE_ANY;
+ CAN_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ SimpleWriteLockHolder holder(&m_bitMaskLock);
+
+ m_bitMask.SetBit(bit);
+}
+
+inline void SynchronizedBitMask::ClearBit(int bit)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ MODE_ANY;
+ CAN_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ SimpleWriteLockHolder holder(&m_bitMaskLock);
+
+ m_bitMask.ClearBit(bit);
+}
+
+inline BOOL SynchronizedBitMask::TestAnyBit()
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ MODE_ANY;
+ CAN_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ SimpleReadLockHolder holder(&m_bitMaskLock);
+
+ return m_bitMask.TestAnyBit();
+}
+
+inline void SynchronizedBitMask::ClearAllBits()
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ MODE_ANY;
+ CAN_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ SimpleWriteLockHolder holder(&m_bitMaskLock);
+
+ m_bitMask.ClearAllBits();
+}
+
+#endif // _BITMASK_INL_
+
diff --git a/lib/coreclr/src/inc/bitposition.h b/lib/coreclr/src/inc/bitposition.h
new file mode 100644
index 0000000000..df7915546a
--- /dev/null
+++ b/lib/coreclr/src/inc/bitposition.h
@@ -0,0 +1,59 @@
+// 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.
+
+#ifndef _BITPOSITION_H_
+#define _BITPOSITION_H_
+
+//------------------------------------------------------------------------
+// BitPosition: Return the position of the single bit that is set in 'value'.
+//
+// Return Value:
+// The position (0 is LSB) of bit that is set in 'value'
+//
+// Notes:
+// 'value' must have exactly one bit set.
+// The algorithm is as follows:
+// - PRIME is a prime bigger than sizeof(unsigned int), which is not of the
+// form 2^n-1.
+// - Taking the modulo of 'value' with this will produce a unique hash for all
+// powers of 2 (which is what "value" is).
+// - Entries in hashTable[] which are -1 should never be used. There
+// should be PRIME-8*sizeof(value) entries which are -1 .
+//
+inline
+unsigned BitPosition(unsigned value)
+{
+ _ASSERTE((value != 0) && ((value & (value-1)) == 0));
+#if defined(_ARM_) && defined(__llvm__)
+ // use intrinsic functions for arm32
+ // this is applied for LLVM only but it may work for some compilers
+ DWORD index = __builtin_clz(__builtin_arm_rbit(value));
+#elif !defined(_AMD64_)
+ const unsigned PRIME = 37;
+
+ static const char hashTable[PRIME] =
+ {
+ -1, 0, 1, 26, 2, 23, 27, -1, 3, 16,
+ 24, 30, 28, 11, -1, 13, 4, 7, 17, -1,
+ 25, 22, 31, 15, 29, 10, 12, 6, -1, 21,
+ 14, 9, 5, 20, 8, 19, 18
+ };
+
+ _ASSERTE(PRIME >= 8*sizeof(value));
+ _ASSERTE(sizeof(hashTable) == PRIME);
+
+
+ unsigned hash = value % PRIME;
+ unsigned index = hashTable[hash];
+ _ASSERTE(index != (unsigned char)-1);
+#else
+ // not enabled for x86 because BSF is extremely slow on Atom
+ // (15 clock cycles vs 1-3 on any other Intel CPU post-P4)
+ DWORD index;
+ BitScanForward(&index, value);
+#endif
+ return index;
+}
+
+#endif
diff --git a/lib/coreclr/src/inc/bitvector.h b/lib/coreclr/src/inc/bitvector.h
new file mode 100644
index 0000000000..a4181dbb8a
--- /dev/null
+++ b/lib/coreclr/src/inc/bitvector.h
@@ -0,0 +1,462 @@
+// 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.
+
+
+/***************************************************************************/
+/* BitVector.h */
+/***************************************************************************/
+// Routines to support a growable bitvector
+/***************************************************************************/
+
+#ifndef BITVECTOR_H
+#define BITVECTOR_H 1
+
+
+#ifndef LIMITED_METHOD_CONTRACT
+#define LIMITED_METHOD_CONTRACT
+#define UNDEF_LIMITED_METHOD_CONTRACT
+#endif
+
+#ifndef WRAPPER_NO_CONTRACT
+#define WRAPPER_NO_CONTRACT
+#define UNDEF_WRAPPER_NO_CONTRACT
+#endif
+
+#ifndef SUPPORTS_DAC
+#define SUPPORTS_DAC
+#define UNDEF_SUPPORTS_DAC
+#endif
+
+#ifndef _ASSERTE
+#define _ASSERTE(x)
+#define UNDEF_ASSERTE
+#endif
+
+#define USE_BITVECTOR 1
+#if USE_BITVECTOR
+
+/* The bitvector class is meant to be a drop in replacement for an integer
+ (that is you use it like an integer), however it grows as needed.
+
+ Features:
+ plug compatible with normal integers;
+ grows as needed
+ Optimized for the small case when the vector fits in machine word
+ Uses one machine word if vector fits in machine word (minus a bit)
+
+ Some caveates:
+ You should use mutator operators &=, |= ... instead of the
+ non-mutators whenever possible to avoid creating a temps
+
+ Specifically did NOT supply automatic coersions to
+ and from short types so that the programmer is aware of
+ when code was being injected on his behalf. The upshot of this
+ is that you have to use the BitVector() toUnsigned() to convert
+*/
+
+/***************************************************************************/
+
+class BitVector {
+ // Set this to be unsigned char to do testing, should be UINT_PTR for real life
+
+ typedef UINT_PTR ChunkType; // The size of integer type that the machine can operate on directly
+// typedef BYTE ChunkType; // Use for testing
+
+ // Maximum number of bits in our bitvector
+#define MAX_PTRARG_OFS 1024
+
+ enum {
+ IS_BIG = 1, // The low bit is used to discrimate m_val and m_vals
+ CHUNK_BITS = sizeof(ChunkType)*8, // The number of bits that we can manipuate as a chunk
+ SMALL_BITS = CHUNK_BITS - 1, // The number of bits we can fit in the small representation
+// SMALL_BITS = 5, // TESTING ONLY: The number of bits we can fit in the small representation
+ VALS_COUNT = MAX_PTRARG_OFS / CHUNK_BITS, // The number of ChunkType elements in the Vals array
+ };
+
+public:
+ BitVector()
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ m_val = 0;
+ }
+
+ BOOL isBig() const
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ return ((m_val & IS_BIG) != 0);
+ }
+
+ void toBig()
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ if (!isBig())
+ {
+ doBigInit(smallBits());
+ }
+ }
+
+ explicit BitVector(ChunkType arg)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if (arg > MaxVal)
+ {
+ doBigInit(arg);
+ }
+ else
+ {
+ m_val = ChunkType(arg << 1);
+ }
+ }
+
+ BitVector(ChunkType arg, UINT shift)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if ((arg > MaxVal) || (shift >= SMALL_BITS) || (arg > (MaxVal >> shift)))
+ {
+ doBigInit(arg);
+ doBigLeftShiftAssign(shift);
+ }
+ else
+ {
+ m_val = ChunkType(arg << (shift+1));
+ }
+ }
+
+#define CONSTRUCT_ptrArgTP(arg,shift) BitVector((arg), (shift))
+
+ BitVector(const BitVector& arg)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if (arg.isBig())
+ {
+ doBigInit(arg);
+ }
+ else
+ {
+ m_val = arg.m_val;
+ }
+ }
+
+ void operator <<=(unsigned shift)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if ((m_val == 0) || (shift == 0)) // Zero is a special case, don't need to do anything
+ return;
+
+ if (isBig() || (shift >= SMALL_BITS) || (m_val > (MaxVal >> (shift-1))))
+ {
+ doBigLeftShiftAssign(shift);
+ }
+ else
+ {
+ m_val <<= shift;
+ }
+ }
+
+ void operator >>=(unsigned shift)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if (isBig())
+ {
+ doBigRightShiftAssign(shift);
+ }
+ else
+ {
+ m_val >>= shift;
+ m_val &= ~IS_BIG; // clear the isBig bit if it got set
+ }
+ }
+
+ void operator |=(const BitVector& arg)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if (((m_val | arg.m_val) & IS_BIG) != 0)
+ {
+ doBigOrAssign(arg);
+ }
+ else
+ {
+ m_val |= arg.m_val;
+ }
+ }
+
+ // Note that that is set difference, not subtration
+ void operator -=(const BitVector& arg)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if (((m_val | arg.m_val) & IS_BIG) != 0)
+ {
+ doBigDiffAssign(arg);
+ }
+ else
+ {
+ m_val &= ~arg.m_val;
+ }
+ }
+
+ void operator &=(const BitVector& arg)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if (((m_val | arg.m_val) & IS_BIG) != 0)
+ {
+ doBigAndAssign(arg);
+ }
+ else
+ {
+ m_val &= arg.m_val;
+ }
+ }
+
+ friend void setDiff(BitVector& target, const BitVector& arg)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ target -= arg;
+ }
+
+ friend BOOL intersect(const BitVector& arg1, const BitVector& arg2)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if (((arg1.m_val | arg2.m_val) & IS_BIG) != 0)
+ {
+ return arg1.doBigIntersect(arg2);
+ }
+ else
+ {
+ return ((arg1.m_val & arg2.m_val) != 0);
+ }
+ }
+
+ BOOL operator ==(const BitVector& arg) const
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if ((m_val | arg.m_val) & IS_BIG)
+ {
+ return doBigEquals(arg);
+ }
+ else
+ {
+ return m_val == arg.m_val;
+ }
+ }
+
+ BOOL operator !=(const BitVector& arg) const
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ return !(*this == arg);
+ }
+
+ friend ChunkType toUnsigned(const BitVector& arg)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ if (arg.isBig())
+ {
+ return arg.m_vals.m_chunks[0]; // Note truncation
+ }
+ else
+ {
+ return arg.smallBits();
+ }
+ }
+
+ // Note that we require the invariant that zero is always stored in the
+ // small form so that this works bitvector is zero iff (m_val == 0)
+ friend BOOL isZero(const BitVector& arg)
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ return arg.m_val == 0;
+ }
+
+ /* currently only used in asserts */
+ BitVector operator &(const BitVector& arg) const
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ BitVector ret = *this;
+ ret &= arg;
+ return ret;
+ }
+
+ int NumBits() const;
+
+private:
+
+ static const ChunkType MaxVal = ((ChunkType)1 << SMALL_BITS) - 1; // Maximum value that can be stored in m_val
+
+ // This is the structure that we use when the bit vector overflows.
+ // It is a simple vector.
+ struct Vals {
+ unsigned m_encodedLength; // An encoding of the current length of the 'm_chunks' array
+ ChunkType m_chunks[VALS_COUNT];
+
+ BOOL isBig() const
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ return ((m_encodedLength & IS_BIG) != 0);
+ }
+
+ unsigned GetLength() const
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ if (isBig())
+ {
+ unsigned length = (m_encodedLength >> 1);
+ _ASSERTE(length > 0);
+ return length;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ void SetLength(unsigned length)
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ _ASSERTE(length > 0);
+ _ASSERTE(length <= VALS_COUNT);
+
+ m_encodedLength = (ChunkType) (length << 1);
+ m_encodedLength |= (ChunkType) IS_BIG;
+ }
+ };
+
+ //
+ // This is the instance data for the bitvector
+ //
+ // We discrimininate on this
+ union {
+ ChunkType m_val; // if m_val bit 0 is false, then bits 1-N are the bit vector
+ Vals m_vals; // if m_val bit 1 is true, then use Vals
+ };
+
+
+ ChunkType smallBits() const
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ _ASSERTE(!isBig());
+ return (m_val >> 1);
+ }
+
+#ifdef STRIKE
+ void doBigInit(ChunkType arg) {}
+#else
+ void doBigInit(ChunkType arg);
+#endif
+ void doBigInit(const BitVector& arg);
+ void doBigLeftShiftAssign(unsigned arg);
+ void doBigRightShiftAssign(unsigned arg);
+ void doBigDiffAssign(const BitVector&);
+ void doBigAndAssign(const BitVector&);
+ void doBigOrAssign(const BitVector& arg);
+ BOOL doBigEquals(const BitVector&) const;
+ BOOL doBigIntersect(const BitVector&) const;
+};
+
+typedef BitVector ptrArgTP;
+
+#else // !USE_BITVECTOR
+
+typedef unsigned __int64 ptrArgTP;
+
+ // Maximum number of bits in our bitvector
+#define MAX_PTRARG_OFS (sizeof(ptrArgTP) * 8)
+
+#define CONSTRUCT_ptrArgTP(arg,shift) (((ptrArgTP) (arg)) << (shift))
+
+inline BOOL isZero(const ptrArgTP& arg)
+{
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+ return (arg == 0);
+}
+
+inline ptrArgTP toUnsigned(const ptrArgTP& arg)
+{
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+ return arg;
+}
+
+inline void setDiff(ptrArgTP& target, const ptrArgTP& arg)
+{
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ target &= ~arg;
+}
+
+inline BOOL intersect(const ptrArgTP arg1, const ptrArgTP arg2)
+{
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ return ((arg1 & arg2) != 0);
+}
+
+#endif // !USE_BITVECTOR
+
+#ifdef UNDEF_LIMITED_METHOD_CONTRACT
+#undef LIMITED_METHOD_CONTRACT
+#undef UNDEF_LIMITED_METHOD_CONTRACT
+#endif
+
+#ifdef UNDEF_WRAPPER_NO_CONTRACT
+#undef WRAPPER_NO_CONTRACT
+#undef UNDEF_WRAPPER_NO_CONTRACT
+#endif
+
+#ifdef UNDEF_SUPPORTS_DAC
+#undef SUPPORTS_DAC
+#undef UNDEF_SUPPORTS_DAC
+#endif
+
+#ifdef UNDEF_ASSERTE
+#undef _ASSERTE
+#undef UNDEF_ASSERTE
+#endif
+
+#endif // BITVECTOR_H
diff --git a/lib/coreclr/src/inc/blobfetcher.h b/lib/coreclr/src/inc/blobfetcher.h
new file mode 100644
index 0000000000..0c640f0d6d
--- /dev/null
+++ b/lib/coreclr/src/inc/blobfetcher.h
@@ -0,0 +1,174 @@
+// 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.
+//*****************************************************************************
+// CBlobFetcher - it fetches binary chunks, similar to new, but more controlled
+//
+// Fast, dynamic, memory management which doesn't relocate blocks
+// m_pIndex has array of pillars, where each pillar starts off empty and has
+// just-in-time allocation. As each pillar fills up, we move to the next pillar
+// If the entire array of pillars fill up, we need to allocate a new array and
+// copy the pillars over. But the actual data returned from GetBlock() never
+// gets moved. So everyone's happy.
+//
+//*****************************************************************************
+
+
+#ifndef __BLOB_FETCHER_H_
+#define __BLOB_FETCHER_H_
+
+#include
+
+
+class CBlobFetcher
+{
+protected:
+
+ class CPillar {
+ public:
+ CPillar();
+ ~CPillar();
+
+ void SetAllocateSize(unsigned nSize);
+ unsigned GetAllocateSize() const;
+
+ char* MakeNewBlock(unsigned len, unsigned pad);
+ void StealDataFrom(CPillar & src);
+ unsigned GetDataLen() const;
+ char* GetRawDataStart();
+ BOOL Contains(__in char *ptr);
+ ULONG32 GetOffset(__in char *ptr);
+
+ protected:
+ unsigned m_nTargetSize; // when we allocate, make it this large
+
+ // Make these public so CBlobFetcher can do easy manipulation
+ public:
+ char* m_dataAlloc;
+ char* m_dataStart;
+ char* m_dataCur;
+ char* m_dataEnd;
+ };
+
+
+ CPillar * m_pIndex; // array of pillars
+
+ unsigned m_nIndexMax; // actual size of m_ppIndex
+ unsigned m_nIndexUsed; // current pillar, so start at 0
+
+ unsigned m_nDataLen; // sum of all pillars' lengths
+
+// Don't allow these because they'll mess up the ownership
+ CBlobFetcher(const CBlobFetcher & src);
+ CBlobFetcher& operator=(const CBlobFetcher & src);
+
+public:
+#if defined(_WIN64)
+ // needs to be 64 so that we can purposefully cache align code in ngen'd images
+ enum { maxAlign = 64 }; // maximum alignment we support
+#else
+ enum { maxAlign = 32 }; // maximum alignment we support
+#endif
+ CBlobFetcher();
+ ~CBlobFetcher();
+
+// get a block to write on (use instead of write to avoid copy)
+ char * MakeNewBlock(unsigned int nSize, unsigned align=1);
+
+// Index segment as if this were linear
+ char * ComputePointer(unsigned offset) const;
+
+// Determine if pointer came from this fetcher
+ BOOL ContainsPointer(__in char *ptr) const;
+
+// Find an offset as if this were linear
+ unsigned ComputeOffset(__in char *ptr) const;
+
+// Write out the section to the stream
+ HRESULT Write(HANDLE file);
+
+// Write out the section to memory
+ HRESULT WriteMem(void ** pMem);
+
+// Get the total length of all our data (sum of all the pillar's data length's)
+// cached value, so light weight & no computations
+ unsigned GetDataLen() const;
+
+ HRESULT Merge(CBlobFetcher *destination);
+
+// Set the blob fetcher to slow growth mode. This should be done before any allocations
+ void SetInitialGrowth(unsigned growth);
+};
+
+
+//*****************************************************************************
+// Inlines
+//*****************************************************************************
+
+// Set the size that the Pillar will allocate if we call getBlock()
+inline void CBlobFetcher::CPillar::SetAllocateSize(unsigned nSize)
+{
+ LIMITED_METHOD_CONTRACT;
+ m_nTargetSize = nSize;
+}
+
+// Get the size we will allocate so we can decide if we need to change it
+// This is not the same as the GetDataLen() and is only useful
+// before we do the allocation
+inline unsigned CBlobFetcher::CPillar::GetAllocateSize() const
+{
+ LIMITED_METHOD_CONTRACT;
+ return m_nTargetSize;
+}
+
+inline char* CBlobFetcher::CPillar::GetRawDataStart()
+{
+ LIMITED_METHOD_CONTRACT;
+ return m_dataStart;
+}
+
+inline BOOL CBlobFetcher::CPillar::Contains(__in char *ptr)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return ptr >= m_dataStart && ptr < m_dataCur;
+}
+
+inline ULONG32 CBlobFetcher::CPillar::GetOffset(__in char *ptr)
+{
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(Contains(ptr));
+
+ return (ULONG32)(ptr - m_dataStart);
+}
+
+//-----------------------------------------------------------------------------
+// Calculate the length of data being used, (not the length allocated)
+//-----------------------------------------------------------------------------
+inline unsigned CBlobFetcher::CPillar::GetDataLen() const
+{
+ LIMITED_METHOD_CONTRACT;
+
+ _ASSERTE((m_dataCur >= m_dataStart) && (m_dataCur <= m_dataEnd));
+
+ return (unsigned)(m_dataCur - m_dataStart);
+}
+
+inline unsigned CBlobFetcher::GetDataLen() const
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return m_nDataLen;
+}
+
+// Set the blob fetcher to slow growth mode. This should be done before any allocations
+inline void CBlobFetcher::SetInitialGrowth(unsigned growth)
+{
+ _ASSERTE(GetDataLen() == 0);
+ if (GetDataLen() == 0)
+ {
+ m_pIndex[0].SetAllocateSize(growth);
+ }
+}
+
+#endif // __BLOB_FETCHER_H_
diff --git a/lib/coreclr/src/inc/cahlpr.h b/lib/coreclr/src/inc/cahlpr.h
new file mode 100644
index 0000000000..903d3abddf
--- /dev/null
+++ b/lib/coreclr/src/inc/cahlpr.h
@@ -0,0 +1,41 @@
+// 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.
+//*****************************************************************************
+// File: CAHLPR.H
+//
+//
+//
+//*****************************************************************************
+#ifndef __CAHLPR_H__
+#define __CAHLPR_H__
+
+#include "caparser.h"
+
+//*****************************************************************************
+// This class assists in the parsing of CustomAttribute blobs.
+//*****************************************************************************
+struct CaValue
+{
+ union
+ {
+ signed __int8 i1;
+ unsigned __int8 u1;
+ signed __int16 i2;
+ unsigned __int16 u2;
+ signed __int32 i4;
+ unsigned __int32 u4;
+ signed __int64 i8;
+ unsigned __int64 u8;
+ float r4;
+ double r8;
+ struct
+ {
+ LPCUTF8 pStr;
+ ULONG cbStr;
+ } str;
+ };
+ unsigned __int8 tag;
+};
+
+#endif // __CAHLPR_H__
diff --git a/lib/coreclr/src/inc/caparser.h b/lib/coreclr/src/inc/caparser.h
new file mode 100644
index 0000000000..0dfbb918b2
--- /dev/null
+++ b/lib/coreclr/src/inc/caparser.h
@@ -0,0 +1,377 @@
+// 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.
+//
+// File: caparser.h
+//
+
+
+//
+
+//
+// ============================================================================
+
+#ifndef __CAPARSER_H__
+#define __CAPARSER_H__
+
+#include "stgpooli.h"
+
+class CustomAttributeParser {
+public:
+ CustomAttributeParser( // Constructor for CustomAttributeParser.
+ const void *pvBlob, // Pointer to the CustomAttribute blob.
+ ULONG cbBlob) // Size of the CustomAttribute blob.
+ : m_pbCur(reinterpret_cast(pvBlob)),
+ m_pbBlob(reinterpret_cast(pvBlob)),
+ m_cbBlob(cbBlob)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+private:
+ signed __int8 GetI1()
+ {
+ LIMITED_METHOD_CONTRACT;
+ signed __int8 tmp = *reinterpret_cast(m_pbCur);
+ m_pbCur += sizeof(signed __int8);
+ return tmp;
+ }
+ unsigned __int8 GetU1()
+ {
+ LIMITED_METHOD_CONTRACT;
+ unsigned __int8 tmp = *reinterpret_cast(m_pbCur);
+ m_pbCur += sizeof(unsigned __int8);
+ return tmp;
+ }
+
+ signed __int16 GetI2()
+ {
+ LIMITED_METHOD_CONTRACT;
+ signed __int16 tmp = GET_UNALIGNED_VAL16(m_pbCur);
+ m_pbCur += sizeof(signed __int16);
+ return tmp;
+ }
+ unsigned __int16 GetU2()
+ {
+ LIMITED_METHOD_CONTRACT;
+ unsigned __int16 tmp = GET_UNALIGNED_VAL16(m_pbCur);
+ m_pbCur += sizeof(unsigned __int16 );
+ return tmp;
+ }
+
+ signed __int32 GetI4()
+ {
+ LIMITED_METHOD_CONTRACT;
+ signed __int32 tmp = GET_UNALIGNED_VAL32(m_pbCur);
+ m_pbCur += sizeof(signed __int32 );
+ return tmp;
+ }
+ unsigned __int32 GetU4()
+ {
+ LIMITED_METHOD_CONTRACT;
+ unsigned __int32 tmp = GET_UNALIGNED_VAL32(m_pbCur);
+ m_pbCur += sizeof(unsigned __int32 );
+ return tmp;
+ }
+
+ signed __int64 GetI8()
+ {
+ LIMITED_METHOD_CONTRACT;
+ signed __int64 tmp = GET_UNALIGNED_VAL64(m_pbCur);
+ m_pbCur += sizeof(signed __int64 );
+ return tmp;
+ }
+ unsigned __int64 GetU8()
+ {
+ LIMITED_METHOD_CONTRACT;
+ unsigned __int64 tmp = GET_UNALIGNED_VAL64(m_pbCur);
+ m_pbCur += sizeof(unsigned __int64 );
+ return tmp;
+ }
+
+public:
+ float GetR4()
+ {
+ LIMITED_METHOD_CONTRACT;
+ __int32 tmp = GET_UNALIGNED_VAL32(m_pbCur);
+ _ASSERTE(sizeof(__int32) == sizeof(float));
+ m_pbCur += sizeof(float);
+ return (float &)tmp;
+ }
+
+ double GetR8()
+ {
+ LIMITED_METHOD_CONTRACT;
+ __int64 tmp = GET_UNALIGNED_VAL64(m_pbCur);
+ _ASSERTE(sizeof(__int64) == sizeof(double));
+ m_pbCur += sizeof(double);
+ return (double &)tmp;
+ }
+
+private:
+ unsigned __int16 GetProlog()
+ {
+ WRAPPER_NO_CONTRACT;
+ unsigned __int16 val;
+ VERIFY(SUCCEEDED(GetProlog(&val)));
+ return val;
+ }
+
+ LPCUTF8 GetString(ULONG *pcbString)
+ {
+ WRAPPER_NO_CONTRACT;
+ LPCUTF8 val;
+ VERIFY(SUCCEEDED(GetString(&val, pcbString)));
+ return val;
+ }
+
+public:
+ HRESULT GetI1(signed __int8 *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (BytesLeft() < (int) sizeof(signed __int8))
+ return META_E_CA_INVALID_BLOB;
+ *pVal = GetI1();
+ return S_OK;
+ }
+
+ HRESULT GetTag(CorSerializationType *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+ HRESULT hr;
+ signed __int8 tmp;
+ IfFailRet(GetI1(&tmp));
+ *pVal = (CorSerializationType)((unsigned __int8)tmp);
+ return hr;
+ }
+
+ HRESULT GetU1(unsigned __int8 *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (BytesLeft() < (int) sizeof(unsigned __int8))
+ return META_E_CA_INVALID_BLOB;
+ *pVal = GetU1();
+ return S_OK;
+ }
+
+ HRESULT GetI2(signed __int16 *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (BytesLeft() < (int) sizeof(signed __int16))
+ return META_E_CA_INVALID_BLOB;
+ *pVal = GetI2();
+ return S_OK;
+ }
+ HRESULT GetU2(unsigned __int16 *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (BytesLeft() < (int) sizeof(unsigned __int16))
+ return META_E_CA_INVALID_BLOB;
+ *pVal = GetU2();
+ return S_OK;
+ }
+
+ HRESULT GetI4(signed __int32 *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (BytesLeft() < (int) sizeof(signed __int32))
+ return META_E_CA_INVALID_BLOB;
+ *pVal = GetI4();
+ return S_OK;
+ }
+ HRESULT GetU4(unsigned __int32 *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (BytesLeft() < (int) sizeof(unsigned __int32))
+ return META_E_CA_INVALID_BLOB;
+ *pVal = GetU4();
+ return S_OK;
+ }
+
+ HRESULT GetI8(signed __int64 *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (BytesLeft() < (int) sizeof(signed __int64))
+ return META_E_CA_INVALID_BLOB;
+ *pVal = GetI8();
+ return S_OK;
+ }
+ HRESULT GetU8(unsigned __int64 *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (BytesLeft() < (int) sizeof(unsigned __int64))
+ return META_E_CA_INVALID_BLOB;
+ *pVal = GetU8();
+ return S_OK;
+ }
+
+ HRESULT GetR4(float *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (BytesLeft() < (int) sizeof(float))
+ return META_E_CA_INVALID_BLOB;
+ *pVal = GetR4();
+ return S_OK;
+ }
+ HRESULT GetR8(double *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (BytesLeft() < (int) sizeof(double))
+ return META_E_CA_INVALID_BLOB;
+ *pVal = GetR8();
+ return S_OK;
+ }
+
+ HRESULT GetProlog(unsigned __int16 *pVal)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ m_pbCur = m_pbBlob;
+
+ if (BytesLeft() < (int)(sizeof(BYTE) * 2))
+ return META_E_CA_INVALID_BLOB;
+
+ return GetU2(pVal);
+ }
+
+ // Added for compatibility with anyone that may emit
+ // blobs where the prolog is the only incorrect data.
+ HRESULT SkipProlog()
+ {
+ unsigned __int16 val;
+ return GetProlog(&val);
+ }
+
+ HRESULT ValidateProlog()
+ {
+ HRESULT hr;
+ unsigned __int16 val;
+ IfFailRet(GetProlog(&val));
+
+ if (val != 0x0001)
+ return META_E_CA_INVALID_BLOB;
+
+ return hr;
+ }
+
+ //
+ // IMPORTANT: the returned string is typically not null-terminated.
+ //
+ // This can return any of three distinct valid results:
+ // - NULL string, indicated by *pszString==NULL, *pcbString==0
+ // - empty string, indicated by *pszString!=NULL, *pcbString==0
+ // - non-empty string, indicated by *pdzString!=NULL, *pcbString!=0
+ // If you expect non-null or non-empty strings in your usage scenario,
+ // call the GetNonNullString and GetNonEmptyString helpers below.
+ //
+ HRESULT GetString(LPCUTF8 *pszString, ULONG *pcbString)
+ {
+ STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_FORBID_FAULT;
+
+ HRESULT hr;
+
+ if (BytesLeft() == 0)
+ { // Need to check for NULL string sentinal (see below),
+ // so need to have at least one byte to read.
+ IfFailRet(META_E_CA_INVALID_BLOB);
+ }
+
+ if (*m_pbCur == 0xFF)
+ { // 0xFF indicates the NULL string, which is semantically
+ // different than the empty string.
+ *pszString = NULL;
+ *pcbString = 0;
+ m_pbCur++;
+ return S_OK;
+ }
+
+ // Get the length, pointer to data following the length.
+ return GetData((BYTE const **)pszString, pcbString);
+ }
+
+ //
+ // This can return any of two distinct valid results:
+ // - empty string, indicated by *pszString!=NULL, *pcbString==0
+ // - non-empty string, indicated by *pszString!=NULL, *pcbString!=0
+ // If you expect non-null or non-empty strings in your usage scenario,
+ // call the GetNonNullString and GetNonEmptyString helpers below.
+ //
+ HRESULT GetNonNullString(LPCUTF8 *pszString, ULONG *pcbString)
+ {
+ STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_FORBID_FAULT;
+
+ HRESULT hr;
+
+ IfFailRet(GetString(pszString, pcbString));
+
+ if (*pszString == NULL)
+ {
+ return META_E_CA_INVALID_BLOB;
+ }
+
+ return S_OK;
+ }
+
+ //
+ // This function will only return success if the string is valid,
+ // non-NULL and non-empty; i.e., *pszString!=NULL, *pcbString!=0
+ //
+ HRESULT GetNonEmptyString(LPCUTF8 *pszString, ULONG *pcbString)
+ {
+ STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_FORBID_FAULT;
+
+ HRESULT hr;
+
+ IfFailRet(GetNonNullString(pszString, pcbString));
+
+ if (*pcbString == 0)
+ {
+ return META_E_CA_INVALID_BLOB;
+ }
+
+ return S_OK;
+ }
+
+ // IMPORTANT: do not use with string fetching - use GetString instead.
+ HRESULT GetData(BYTE const **ppbData, ULONG *pcbData)
+ {
+ HRESULT hr;
+ IfFailRet(CPackedLen::SafeGetData(m_pbCur, m_pbBlob + m_cbBlob, pcbData, ppbData));
+ // Move past the data we just recovered
+ m_pbCur = *ppbData + *pcbData;
+
+ return S_OK;
+ }
+
+ // IMPORTANT: do not use with string fetching - use GetString instead.
+ HRESULT GetPackedValue(ULONG *pcbData)
+ {
+ return CPackedLen::SafeGetLength(m_pbCur, m_pbBlob + m_cbBlob, pcbData, &m_pbCur);
+ }
+
+ int BytesLeft()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return (int)(m_cbBlob - (m_pbCur - m_pbBlob));
+ }
+
+private:
+ const BYTE *m_pbCur;
+ const BYTE *m_pbBlob;
+ ULONG m_cbBlob;
+};
+
+#endif // __CAPARSER_H__
diff --git a/lib/coreclr/src/inc/ceefilegenwriter.h b/lib/coreclr/src/inc/ceefilegenwriter.h
new file mode 100644
index 0000000000..8bfea464cc
--- /dev/null
+++ b/lib/coreclr/src/inc/ceefilegenwriter.h
@@ -0,0 +1,245 @@
+// 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.
+// ===========================================================================
+// File: CeeFileGenWriter.h
+//
+// ===========================================================================
+
+#ifndef _CEEFILEGENWRITER_H_
+#define _CEEFILEGENWRITER_H_
+//
+
+// CeeFileGenWriter contains all the code necessary to actually write an exe
+// while CCeeGen contains everything else. This lets CeeGen.exe and the VM
+// share more code without forcing the VM to carry the extra code to write an
+// exe.
+#include
+#include "ceegen.h"
+#include "iceefilegen.h"
+
+class PEWriter;
+class CeeFileGenWriter;
+
+// default setting for PE file
+const UINT32 CEE_IMAGE_BASE_32 = 0x00400000;
+const UINT64 CEE_IMAGE_BASE_64 = UI64(0x0000000140000000);
+const int CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION = 4;
+const int CEE_IMAGE_SUBSYSTEM_MINOR_VERSION = 0;
+
+class CeeFileGenWriter : public CCeeGen
+{
+ mdToken m_entryPoint; // token for entry point
+ DWORD m_comImageFlags;
+
+ LPWSTR m_outputFileName;
+ LPWSTR m_resourceFileName;
+ LPWSTR m_libraryName;
+ GUID m_libraryGuid;
+ bool m_dllSwitch;
+
+ ULONG m_iatOffset;
+ DWORD m_dwMacroDefinitionRVA;
+ DWORD m_dwMacroDefinitionSize;
+
+ DWORD m_dwManifestRVA;
+ DWORD m_dwManifestSize;
+
+ DWORD m_dwStrongNameRVA;
+ DWORD m_dwStrongNameSize;
+
+ DWORD m_dwVTableRVA;
+ DWORD m_dwVTableSize;
+
+ bool m_linked;
+ bool m_fixed;
+
+ HRESULT checkForErrors();
+
+ struct IDataDllInfo {
+ const char *m_name;
+ int m_numMethods;
+ const char **m_methodName;
+ int m_iltOffset;
+ int m_ibnOffset;
+ int m_iatOffset;
+ int m_nameOffset;
+ } *m_iDataDlls;
+ int m_dllCount;
+
+ CeeSection *m_iDataSectionIAT;
+ int m_iDataOffsetIAT;
+ char *m_iDataIAT;
+
+#ifdef EMIT_FIXUPS
+
+ CeeSection * m_sectionFixups;
+ IMAGE_DEBUG_DIRECTORY * m_pDebugDir;
+ bool m_fFixupsUpdated;
+ bool m_fEmitFixups;
+
+#endif
+
+ HRESULT allocateIAT();
+public:
+ // Create with one of these two methods, not operator new
+ static HRESULT CreateNewInstance(CCeeGen *pCeeFileGenFrom, CeeFileGenWriter* & pGenWriter,
+ DWORD createFlags = ICEE_CREATE_FILE_PURE_IL);
+ // See ICeeFileGen.h for the definition of the bits used in createFlags
+ static HRESULT CreateNewInstanceEx(CCeeGen *pCeeFileGenFrom, CeeFileGenWriter* & pGenWriter,
+ DWORD createFlags, LPCWSTR seedFileName = NULL);
+
+ virtual HRESULT Cleanup();
+
+ PEWriter &getPEWriter();
+
+ HRESULT link(); // Layout the sections and assign their starting addresses
+ HRESULT fixup(); // Apply relocations to any pointer data. Also generate PE base relocs
+ HRESULT generateImage(void **ppImage);
+
+ HRESULT setImageBase(size_t imageBase);
+ HRESULT setImageBase64(ULONGLONG imageBase);
+ HRESULT setFileAlignment(ULONG fileAlignment);
+ HRESULT setSubsystem(DWORD subsystem, DWORD major, DWORD minor);
+
+ HRESULT getMethodRVA(ULONG codeOffset, ULONG *codeRVA);
+
+ HRESULT setEntryPoint(mdMethodDef method);
+ mdMethodDef getEntryPoint();
+
+ HRESULT setComImageFlags(DWORD mask);
+ HRESULT clearComImageFlags(DWORD mask);
+ DWORD getComImageFlags();
+
+ HRESULT setOutputFileName(__in LPWSTR outputFileName);
+ LPWSTR getOutputFileName();
+
+ HRESULT setResourceFileName(__in LPWSTR resourceFileName);
+ LPWSTR getResourceFileName();
+
+ HRESULT setLibraryName(__in LPWSTR libraryName);
+ LPWSTR getLibraryName();
+
+ HRESULT setDirectoryEntry(CeeSection §ion, ULONG entry, ULONG size, ULONG offset=0);
+ HRESULT computeSectionOffset(CeeSection §ion, __in char *ptr,
+ unsigned *offset);
+ HRESULT computeOffset(__in char *ptr, CeeSection **pSection,
+ unsigned *offset);
+ HRESULT getCorHeader(IMAGE_COR20_HEADER **ppHeader);
+
+ HRESULT getFileTimeStamp(DWORD *pTimeStamp);
+
+//@FUTURE: this entry point is only here so that down level clients of this interface
+// can import the method by name in the exports table using the original name.
+// These things really ought to be exported through a v-table so there is no
+// name mangling issues. It would make the export table much smaller as well.
+ HRESULT emitLibraryName(IMetaDataEmit *emitter);
+ HRESULT setLibraryGuid(__in LPWSTR libraryGuid);
+
+ HRESULT setDllSwitch(bool dllSwitch);
+ bool getDllSwitch();
+ HRESULT setObjSwitch(bool objSwitch);
+ bool getObjSwitch();
+ HRESULT EmitMacroDefinitions(void *pData, DWORD cData);
+ HRESULT setManifestEntry(ULONG size, ULONG offset);
+ HRESULT setStrongNameEntry(ULONG size, ULONG offset);
+ HRESULT setEnCRvaBase(ULONG dataBase, ULONG rdataBase);
+ HRESULT setVTableEntry(ULONG size, ULONG offset);
+ HRESULT setVTableEntry64(ULONG size, void* ptr);
+
+protected:
+ CeeFileGenWriter(); // ctor is protected
+
+ HRESULT emitResourceSection();
+ HRESULT emitExeMain();
+
+ HRESULT setAddrReloc(UCHAR *instrAddr, DWORD value);
+ HRESULT addAddrReloc(CeeSection &thisSection, UCHAR *instrAddr, DWORD offset, CeeSection *targetSection);
+
+ HRESULT MapTokens(CeeGenTokenMapper *pMapper, IMetaDataImport *pImport);
+ HRESULT MapTokensForMethod(CeeGenTokenMapper *pMapper,BYTE *pCode, LPCWSTR szMethodName);
+
+#ifdef EMIT_FIXUPS
+
+ HRESULT InitFixupSection();
+ HRESULT UpdateFixups();
+ HRESULT setEmitFixups();
+
+#ifdef TEST_EMIT_FIXUPS
+ HRESULT TestEmitFixups();
+#endif
+
+public:
+ HRESULT addFixup(CeeSection& secFixups, unsigned offset, CeeSectionRelocType reloc, CeeSection * relativeTo = NULL, CeeSectionRelocExtra *extra = 0);
+#endif
+};
+
+
+inline PEWriter &CeeFileGenWriter::getPEWriter()
+{
+ return (PEWriter &) *m_peSectionMan;
+}
+
+inline LPWSTR CeeFileGenWriter::getOutputFileName() {
+ return m_outputFileName;
+}
+
+inline LPWSTR CeeFileGenWriter::getResourceFileName() {
+ return m_resourceFileName;
+}
+
+inline HRESULT CeeFileGenWriter::setDllSwitch(bool dllSwitch) {
+ if((m_dllSwitch = dllSwitch)) m_objSwitch = FALSE; return S_OK;
+}
+
+inline bool CeeFileGenWriter::getDllSwitch() {
+ return m_dllSwitch;
+}
+
+inline HRESULT CeeFileGenWriter::setObjSwitch(bool objSwitch) {
+ if((m_objSwitch = objSwitch)) m_dllSwitch = FALSE; return S_OK;
+}
+
+inline bool CeeFileGenWriter::getObjSwitch() {
+ return m_objSwitch;
+}
+
+inline LPWSTR CeeFileGenWriter::getLibraryName() {
+ return m_libraryName;
+}
+
+inline mdMethodDef CeeFileGenWriter::getEntryPoint() {
+ return m_entryPoint;
+}
+
+inline HRESULT CeeFileGenWriter::setEntryPoint(mdMethodDef method) {
+ m_entryPoint = method;
+ return S_OK;
+}
+
+inline HRESULT CeeFileGenWriter::setComImageFlags(DWORD mask) {
+ m_comImageFlags |= mask; return S_OK;
+}
+
+inline HRESULT CeeFileGenWriter::clearComImageFlags(DWORD mask) {
+ m_comImageFlags &= ~mask; return S_OK;
+}
+
+inline DWORD CeeFileGenWriter::getComImageFlags() {
+ return m_comImageFlags;
+}
+
+
+//
+#if defined(_IMAGE_FILE_4K_SECTION_ALIGNMENT_)
+#define IMAGE_NT_OPTIONAL_HDR_SECTION_ALIGNMENT 0x1000
+#else
+#define IMAGE_NT_OPTIONAL_HDR_SECTION_ALIGNMENT 0x2000
+#endif
+
+// The stub is always x86 so we always mark the image as x86
+#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_I386
+
+
+#endif // _CEEFILEGENWRITER_H_
+
diff --git a/lib/coreclr/src/inc/ceegen.h b/lib/coreclr/src/inc/ceegen.h
new file mode 100644
index 0000000000..c7d2af2615
--- /dev/null
+++ b/lib/coreclr/src/inc/ceegen.h
@@ -0,0 +1,437 @@
+// 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.
+// ===========================================================================
+// File: CEEGEN.H
+//
+// ===========================================================================
+
+#ifndef _CEEGEN_H_
+#define _CEEGEN_H_
+
+#include "cor.h"
+#include "iceefilegen.h"
+#include "ceegentokenmapper.h"
+
+class CeeSection;
+class CeeSectionString;
+class CCeeGen;
+class PESectionMan;
+class PESection;
+
+typedef DWORD StringRef;
+
+#if 0
+
+ This is a description of the current implementation of these types for generating
+ CLR modules.
+
+ ICeeGen - interface to generate in-memory CLR module.
+
+ CCeeGen - implementation of ICeeGen. Currently it uses both CeeSections
+ as well as PESections (inside PESectionMan), and maintains a
+ 1:1 relation between them. This is ugly.
+
+ CeeFileGenWriter - Provides functionality to write in-memory module to
+ PE format file. Uses PEWriter (m_pSectionMan) for
+ file-writing functionality
+
+ PEWriter - It can generate a PE format file. It also knows to apply
+ pointer relocs when it lays out the PESections.
+
+
+ ICeeFileGen - Interface used by compilers, ngen, etc, to generate
+ a CLR file.
+ Has a bunch of methods to emit signatures, tokens, methods,
+ etc which are not implemented. These are left over from before
+
+ +----------------------------+
+ | ICeeGen |
+ | |
+ | COM-style version of |
+ | ICeeFileGen. HCEEFILE is |
+ | replaced with "this" |
+ +-------------------------+ | |
+ | CeeSectionImpl | +----------------------------+
+ +-------------------------+ |
+ | | |
+ | | v
+ | v +---------------------------+
+ | +------------+ | CCeeGen |
+ | | | +---------------------------+
+ | | CeeSection | contains | |
+ | | |<-------------| CeeSection* m_sections |
+ | +------------+ | |
+ | /| PESectionMan m_pSectionMan|
+ | / | |
+ | +-----------------+ / +---------------------------+
+ v | PESectionMan |<----+ |
+ +-----------+ | | contains |
+ | PESection | +-----------------+ |
+ | | contains | PESection * | v
+ | |<----------| sectStart, | +------------------------------+
+ +-----------+ | sectCur, | | CeeFileGenWriter |
+ | sectEnd | +------------------------------+
+ +-----------------+ | Does meta-data specific |
+ | | stuff and then dispatches to |
+ | | m_pSectionMan.PEWriter::***()|
+ | | |
+ v +------------------------------+
+ +------------------------+ ^
+ | PEWriter | |wraps
+ +------------------------+ |
+ | Low -level file writer | +----------------------------+
+ | Knows how to do | | ICeeFileGen |
+ | pointer relocs | | |
+ | | | C-style inteface. Deals |
+ +------------------------+ | with HCEEFILE, HCEESECTION |
+ | etc. It is mostly just a |
+ | thin wrapper for a |
+ | CeeFileGenWriter |
+ +----------------------------+
+
+#endif // 0
+
+// ***** CeeSection classes
+
+class CeeSectionImpl {
+ public:
+ virtual unsigned dataLen() = 0;
+ virtual char * getBlock(
+ unsigned len,
+ unsigned align = 1) = 0;
+ virtual HRESULT addSectReloc(
+ unsigned offset,
+ CeeSection & relativeTo,
+ CeeSectionRelocType reloc = srRelocAbsolute,
+ CeeSectionRelocExtra * extra = NULL) = 0;
+ virtual HRESULT addBaseReloc(
+ unsigned offset,
+ CeeSectionRelocType reloc = srRelocHighLow,
+ CeeSectionRelocExtra * extra = NULL) = 0;
+ virtual HRESULT directoryEntry(unsigned num) = 0;
+ virtual unsigned char * name() = 0;
+ virtual char * computePointer(unsigned offset) const = 0;
+ virtual BOOL containsPointer(__in char * ptr) const = 0;
+ virtual unsigned computeOffset(__in char * ptr) const = 0;
+ virtual unsigned getBaseRVA() = 0;
+ virtual void SetInitialGrowth(unsigned growth) = 0;
+};
+
+class CeeSection {
+ // m_ceeFile allows inter-section communication
+ CCeeGen &m_ceeFile;
+
+ // abstract away implementation to allow inheritance from CeeSection
+ CeeSectionImpl &m_impl;
+
+ public:
+ enum RelocFlags {
+ RELOC_NONE = 0,
+
+ // address should be fixed up to be a RVA not a normal address
+ RELOC_RVA = 1
+ };
+
+ CeeSection(CCeeGen &ceeFile, CeeSectionImpl &impl)
+ : m_ceeFile(ceeFile), m_impl(impl) { LIMITED_METHOD_CONTRACT; }
+
+ virtual ~CeeSection() {LIMITED_METHOD_CONTRACT; }
+
+ // bytes in this section at present
+ unsigned dataLen();
+
+ // section base, after linking
+ unsigned getBaseRVA();
+
+ // get a block to write on (use instead of write to avoid copy)
+ char* getBlock(unsigned len, unsigned align=1);
+
+ // Indicates that the DWORD at 'offset' in the current section should
+ // have the base of section 'relativeTo added to it
+ HRESULT addSectReloc(unsigned offset, CeeSection& relativeTo,
+ CeeSectionRelocType = srRelocAbsolute, CeeSectionRelocExtra *extra = 0);
+ // Add a base reloc for the given offset in the current section
+ virtual HRESULT addBaseReloc(unsigned offset, CeeSectionRelocType reloc = srRelocHighLow, CeeSectionRelocExtra *extra = 0);
+
+
+ // this section will be directory entry 'num'
+ HRESULT directoryEntry(unsigned num);
+
+ // return section name
+ unsigned char *name();
+
+ // simulate the base + offset with a more complex data storage
+ char * computePointer(unsigned offset) const;
+ BOOL containsPointer(__in char *ptr) const;
+ unsigned computeOffset(__in char *ptr) const;
+
+ CeeSectionImpl &getImpl();
+ CCeeGen &ceeFile();
+ void SetInitialGrowth(unsigned growth);
+};
+
+// ***** CCeeGen class
+// Only handles in memory stuff
+// Base class for CeeFileGenWriter (which actually generates PEFiles)
+
+class CCeeGen : public ICeeGen, ICeeGenInternal {
+ LONG m_cRefs;
+ BOOL m_encMode;
+ protected:
+ short m_textIdx; // m_sections[] index for the .text section
+ short m_metaIdx; // m_sections[] index for metadata (.text, or .cormeta for obj files)
+ short m_corHdrIdx; // m_sections[] index for the COM+ header (.text0)
+ short m_stringIdx; // m_sections[] index for strings (.text, or .rdata for EnC)
+ short m_ilIdx; // m_sections[] index for IL (.text)
+ bool m_objSwitch;
+
+ CeeGenTokenMapper *m_pTokenMap;
+ BOOLEAN m_fTokenMapSupported; // temporary to support both models
+ IMapToken *m_pRemapHandler;
+
+ CeeSection **m_sections;
+ short m_numSections;
+ short m_allocSections;
+
+ PESectionMan * m_peSectionMan;
+
+ IMAGE_COR20_HEADER *m_corHeader;
+ DWORD m_corHeaderOffset;
+
+ HRESULT allocateCorHeader();
+
+ HRESULT addSection(CeeSection *section, short *sectionIdx);
+
+ HRESULT setEnCMode();
+
+// Init process: Call static CreateNewInstance() , not operator new
+ protected:
+ HRESULT Init();
+ CCeeGen();
+
+ public:
+
+ virtual ~CCeeGen() {}
+
+ static HRESULT CreateNewInstance(CCeeGen* & pCeeFileGen); // call this to instantiate
+
+ virtual HRESULT Cleanup();
+
+ // ICeeGen interfaces
+
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+ STDMETHODIMP QueryInterface(
+ REFIID riid,
+ void **ppInterface);
+
+ STDMETHODIMP EmitString (
+ __in LPWSTR lpString, // [IN] String to emit
+ ULONG *RVA);
+
+ STDMETHODIMP GetString (
+ ULONG RVA,
+ __inout LPWSTR *lpString);
+
+ STDMETHODIMP AllocateMethodBuffer (
+ ULONG cchBuffer, // [IN] Length of string to emit
+ UCHAR **lpBuffer, // [OUT] Returned buffer
+ ULONG *RVA);
+
+ STDMETHODIMP GetMethodBuffer (
+ ULONG RVA,
+ UCHAR **lpBuffer);
+
+ STDMETHODIMP GetIMapTokenIface (
+ IUnknown **pIMapToken);
+
+ STDMETHODIMP GenerateCeeFile ();
+
+ STDMETHODIMP GetIlSection (
+ HCEESECTION *section);
+
+ STDMETHODIMP GetStringSection (
+ HCEESECTION *section);
+
+ STDMETHODIMP AddSectionReloc (
+ HCEESECTION section,
+ ULONG offset,
+ HCEESECTION relativeTo,
+ CeeSectionRelocType relocType);
+
+ STDMETHODIMP GetSectionCreate (
+ const char *name,
+ DWORD flags,
+ HCEESECTION *section);
+
+ STDMETHODIMP GetSectionDataLen (
+ HCEESECTION section,
+ ULONG *dataLen);
+
+ STDMETHODIMP GetSectionBlock (
+ HCEESECTION section,
+ ULONG len,
+ ULONG align=1,
+ void **ppBytes=0);
+
+ STDMETHODIMP TruncateSection (
+ HCEESECTION section,
+ ULONG len);
+
+ STDMETHODIMP GenerateCeeMemoryImage (void **ppImage);
+
+ STDMETHODIMP ComputePointer (
+ HCEESECTION section,
+ ULONG RVA, // [IN] RVA for method to return
+ UCHAR **lpBuffer); // [OUT] Returned buffer
+
+
+ STDMETHODIMP AddNotificationHandler(IUnknown *pHandler);
+
+ // Write the metadata in "emitter" to the default metadata section is "section" is 0
+ // If 'section != 0, it will put the data in 'buffer'. This
+ // buffer is assumed to be in 'section' at 'offset' and of size 'buffLen'
+ // (should use GetSaveSize to insure that buffer is big enough
+ virtual HRESULT emitMetaData(IMetaDataEmit *emitter,
+ CeeSection* section=0, DWORD offset=0, BYTE* buffer=0, unsigned buffLen=0);
+ virtual HRESULT getMethodRVA(ULONG codeOffset, ULONG *codeRVA);
+
+ STDMETHODIMP SetInitialGrowth(DWORD growth);
+
+ CeeSection &getTextSection();
+ CeeSection &getMetaSection();
+ CeeSection &getCorHeaderSection();
+ CeeSectionString &getStringSection();
+ CeeSection &getIlSection();
+
+ virtual HRESULT getSectionCreate (const char *name, DWORD flags, CeeSection **section=NULL, short *sectionIdx = NULL);
+
+ PESectionMan* getPESectionMan() {
+ LIMITED_METHOD_CONTRACT;
+ return m_peSectionMan;
+ }
+
+ virtual HRESULT getMapTokenIface(IUnknown **pIMapToken, IMetaDataEmit *emitter=0);
+
+ CeeGenTokenMapper *getTokenMapper() {
+ LIMITED_METHOD_CONTRACT;
+ return m_pTokenMap;
+ }
+
+ virtual HRESULT addNotificationHandler(IUnknown *pHandler);
+
+ //Clone is actually a misnomer here. This method will copy all of the
+ //instance variables and then do a deep copy (as necessary) of the sections.
+ //Section data will be appended onto any information already in the section.
+ //This is done to support the DynamicIL -> PersistedIL transform.
+ virtual HRESULT cloneInstance(CCeeGen *destination);
+
+#ifdef EMIT_FIXUPS
+public:
+ virtual HRESULT addFixup(CeeSection& sectionSource, unsigned offset, CeeSectionRelocType reloc, CeeSection * sectionTarget = NULL, CeeSectionRelocExtra *extra = 0) {
+ LIMITED_METHOD_CONTRACT;
+
+ return(E_NOTIMPL);
+ }
+#endif
+};
+
+// ***** CeeSection inline methods
+
+inline unsigned CeeSection::dataLen() {
+ WRAPPER_NO_CONTRACT;
+ return m_impl.dataLen(); }
+
+inline unsigned CeeSection::getBaseRVA() {
+ WRAPPER_NO_CONTRACT;
+ return m_impl.getBaseRVA(); }
+
+inline char *CeeSection::getBlock(unsigned len, unsigned align) {
+ WRAPPER_NO_CONTRACT;
+ return m_impl.getBlock(len, align); }
+
+inline HRESULT CeeSection::addSectReloc(
+ unsigned offset, CeeSection& relativeTo, CeeSectionRelocType reloc, CeeSectionRelocExtra *extra) {
+ WRAPPER_NO_CONTRACT;
+ return(m_impl.addSectReloc(offset, relativeTo, reloc, extra));
+}
+
+inline HRESULT CeeSection::addBaseReloc(unsigned offset, CeeSectionRelocType reloc, CeeSectionRelocExtra *extra) {
+ WRAPPER_NO_CONTRACT;
+ return(m_impl.addBaseReloc(offset, reloc, extra));
+}
+
+
+inline HRESULT CeeSection::directoryEntry(unsigned num) {
+ WRAPPER_NO_CONTRACT;
+ TESTANDRETURN(num < IMAGE_NUMBEROF_DIRECTORY_ENTRIES, E_INVALIDARG);
+ m_impl.directoryEntry(num);
+ return S_OK;
+}
+
+inline CCeeGen &CeeSection::ceeFile() {
+ LIMITED_METHOD_CONTRACT;
+ return m_ceeFile; }
+
+inline CeeSectionImpl &CeeSection::getImpl() {
+ LIMITED_METHOD_CONTRACT;
+ return m_impl; }
+
+inline unsigned char *CeeSection::name() {
+ WRAPPER_NO_CONTRACT;
+ return m_impl.name();
+}
+
+inline char * CeeSection::computePointer(unsigned offset) const
+{
+ WRAPPER_NO_CONTRACT;
+ return m_impl.computePointer(offset);
+}
+
+inline BOOL CeeSection::containsPointer(__in char *ptr) const
+{
+ WRAPPER_NO_CONTRACT;
+ return m_impl.containsPointer(ptr);
+}
+
+inline unsigned CeeSection::computeOffset(__in char *ptr) const
+{
+ WRAPPER_NO_CONTRACT;
+ return m_impl.computeOffset(ptr);
+}
+
+inline void CeeSection::SetInitialGrowth(unsigned growth)
+{
+ WRAPPER_NO_CONTRACT;
+ m_impl.SetInitialGrowth(growth);
+}
+
+// ***** CCeeGen inline methods
+
+inline CeeSection &CCeeGen::getTextSection() {
+ LIMITED_METHOD_CONTRACT;
+
+ return *m_sections[m_textIdx]; }
+
+inline CeeSection &CCeeGen::getMetaSection() {
+ LIMITED_METHOD_CONTRACT;
+
+ return *m_sections[m_metaIdx]; }
+
+inline CeeSection &CCeeGen::getCorHeaderSection() {
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(m_corHdrIdx >= 0);
+ return *m_sections[m_corHdrIdx]; }
+
+inline CeeSectionString &CCeeGen::getStringSection() {
+ LIMITED_METHOD_CONTRACT;
+
+ return *(CeeSectionString*)m_sections[m_stringIdx]; }
+
+inline CeeSection &CCeeGen::getIlSection() {
+ LIMITED_METHOD_CONTRACT;
+
+ return *m_sections[m_ilIdx]; }
+
+#endif
diff --git a/lib/coreclr/src/inc/ceegentokenmapper.h b/lib/coreclr/src/inc/ceegentokenmapper.h
new file mode 100644
index 0000000000..b323ee48b6
--- /dev/null
+++ b/lib/coreclr/src/inc/ceegentokenmapper.h
@@ -0,0 +1,142 @@
+// 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.
+//*****************************************************************************
+// CeeGenTokenMapper.h
+//
+// This helper class tracks mapped tokens from their old value to the new value
+// which can happen when the data is optimized on save.
+//
+//*****************************************************************************
+
+#ifndef __CeeGenTokenMapper_h__
+#define __CeeGenTokenMapper_h__
+
+#include "utilcode.h"
+
+typedef CDynArray TOKENMAP;
+
+#define INDEX_OF_TYPE(type) ((type) >> 24)
+//r#define INDEX_FROM_TYPE(type) case INDEX_OF_TYPE(mdt ## type): return (tkix ## type)
+
+// Define the list of CeeGen tracked tokens
+#define CEEGEN_TRACKED_TOKENS() \
+ CEEGEN_TRACKED_TOKEN(TypeDef) \
+ CEEGEN_TRACKED_TOKEN(InterfaceImpl) \
+ CEEGEN_TRACKED_TOKEN(MethodDef) \
+ CEEGEN_TRACKED_TOKEN(TypeRef) \
+ CEEGEN_TRACKED_TOKEN(MemberRef) \
+ CEEGEN_TRACKED_TOKEN(CustomAttribute) \
+ CEEGEN_TRACKED_TOKEN(FieldDef) \
+ CEEGEN_TRACKED_TOKEN(ParamDef) \
+ CEEGEN_TRACKED_TOKEN(File) \
+ CEEGEN_TRACKED_TOKEN(GenericParam) \
+
+class CCeeGen;
+
+#define CEEGEN_TRACKED_TOKEN(x) tkix ## x,
+
+class CeeGenTokenMapper : public IMapToken
+{
+friend class CCeeGen;
+friend class PESectionMan;
+public:
+ enum
+ {
+ CEEGEN_TRACKED_TOKENS()
+ MAX_TOKENMAP
+ };
+
+ static int IndexForType(mdToken tk);
+
+ CeeGenTokenMapper() : m_pIImport(0), m_cRefs(1), m_pIMapToken(NULL) { LIMITED_METHOD_CONTRACT; }
+ virtual ~CeeGenTokenMapper() {}
+
+//*****************************************************************************
+// IUnknown implementation.
+//*****************************************************************************
+ virtual ULONG STDMETHODCALLTYPE AddRef()
+ {LIMITED_METHOD_CONTRACT; return ++m_cRefs; }
+
+ virtual ULONG STDMETHODCALLTYPE Release()
+ {
+ STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_FORBID_FAULT;
+ SUPPORTS_DAC_HOST_ONLY;
+
+ ULONG cRefs = --m_cRefs;
+ if (cRefs == 0)
+ {
+ if (m_pIMapToken)
+ {
+ m_pIMapToken->Release();
+ m_pIMapToken = NULL;
+ }
+
+ delete this;
+ }
+ return cRefs;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, PVOID *ppIUnk);
+
+//*****************************************************************************
+// Called by the meta data engine when a token is remapped to a new location.
+// This value is recorded in the m_rgMap array based on type and rid of the
+// from token value.
+//*****************************************************************************
+ virtual HRESULT STDMETHODCALLTYPE Map(mdToken tkImp, mdToken tkEmit);
+
+//*****************************************************************************
+// Check the given token to see if it has moved to a new location. If so,
+// return true and give back the new token.
+//*****************************************************************************
+ virtual int HasTokenMoved(mdToken tkFrom, mdToken &tkTo);
+
+ int GetMaxMapSize() const
+ { LIMITED_METHOD_CONTRACT; return (MAX_TOKENMAP); }
+
+ IUnknown *GetMapTokenIface() const
+ { LIMITED_METHOD_CONTRACT; return ((IUnknown *) this); }
+
+
+//*****************************************************************************
+// Hand out a copy of the meta data information.
+//*****************************************************************************
+ virtual HRESULT GetMetaData(IMetaDataImport **ppIImport);
+
+//*****************************************************************************
+// Add another token mapper.
+//*****************************************************************************
+ virtual HRESULT AddTokenMapper(IMapToken *pIMapToken)
+ {
+ STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_FORBID_FAULT;
+
+ // Add the token mapper, if there isn't already one.
+ if (m_pIMapToken == NULL)
+ {
+ m_pIMapToken = pIMapToken;
+ m_pIMapToken->AddRef();
+ return S_OK;
+ }
+ else
+ {
+ _ASSERTE(!"Token mapper already set!");
+ return E_FAIL;
+ }
+ }
+
+protected:
+// m_rgMap is an array indexed by token type. For each type, an array of
+// tokens is kept, indexed by from rid. To see if a token has been moved,
+// do a lookup by type to get the right array, then use the from rid to
+// find the to rid.
+ TOKENMAP m_rgMap[MAX_TOKENMAP];
+ IMetaDataImport *m_pIImport;
+ ULONG m_cRefs; // Ref count.
+ IMapToken *m_pIMapToken;
+
+};
+
+#endif // __CeeGenTokenMapper_h__
diff --git a/lib/coreclr/src/inc/ceesectionstring.h b/lib/coreclr/src/inc/ceesectionstring.h
new file mode 100644
index 0000000000..06a534a0c1
--- /dev/null
+++ b/lib/coreclr/src/inc/ceesectionstring.h
@@ -0,0 +1,55 @@
+// 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.
+// ===========================================================================
+// File: CeeSectionString.h
+//
+// ===========================================================================
+
+#ifndef CeeSectionString_H
+#define CeeSectionString_H
+
+#include
+#include "ceegen.h"
+
+// This class is responsible for managing all the strings that have
+// been emitted for the PE file.
+
+// This class manages the strings that are added to the .rdata section.
+// It keeps track of each string that has been added using a hashtable.
+// The hash table is effectively 2-dimensional. There is a large "virtual
+// hash space" that is used to get a wide hash code distribution. The
+// virtual hash space is mapped into a real hash table where each n
+// hash values in the virtual space fall into a given hash bucket for
+// real hash table size n. Within the bucket, elements are stored in a linked
+// list in-order. When an virtual hash entry corresponds to a given bucket,
+// that bucket is searched for the matching hash id. If not found, it is
+// inserted, otherwise, the value is returned. The idea is that for smaller
+// apps, there won't be a large number of strings, so that collisions are
+// minimal and the length of each bucket's chain is small. For larger
+// numbers of strings, having a large hash space also reduces numbers
+// of collisions, avoiding string compares unless the hash codes match.
+
+struct StringTableEntry;
+
+class CeeSectionString : public CeeSection {
+ enum { MaxRealEntries = 100, MaxVirtualEntries = 10000 };
+ StringTableEntry *stringTable[MaxRealEntries];
+
+ StringTableEntry *createEntry(__in_z LPWSTR target, ULONG hashId);
+ StringTableEntry *findStringInsert(
+ StringTableEntry *&entry, __in_z LPWSTR targetValue, ULONG hashId);
+ void deleteEntries(StringTableEntry *e);
+#ifdef RDATA_STATS
+ int dumpEntries(StringTableEntry *e);
+ void dumpTable();
+#endif
+
+ public:
+ ~CeeSectionString();
+ CeeSectionString(CCeeGen &ceeFile, CeeSectionImpl &impl);
+ virtual HRESULT getEmittedStringRef(__in_z LPWSTR targetValue, StringRef *ref);
+};
+
+#endif
+
diff --git a/lib/coreclr/src/inc/cfi.h b/lib/coreclr/src/inc/cfi.h
new file mode 100644
index 0000000000..d5d77840ec
--- /dev/null
+++ b/lib/coreclr/src/inc/cfi.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef CFI_H_
+#define CFI_H_
+
+#define DWARF_REG_ILLEGAL -1
+enum CFI_OPCODE
+{
+ CFI_ADJUST_CFA_OFFSET, // Offset is adjusted relative to the current one.
+ CFI_DEF_CFA_REGISTER, // New register is used to compute CFA
+ CFI_REL_OFFSET // Register is saved at offset from the current CFA
+};
+
+struct CFI_CODE
+{
+ unsigned char CodeOffset;// Offset from the start of code the frame covers.
+ unsigned char CfiOpCode;
+ short DwarfReg; // Dwarf register number. 0~32 for x64.
+ int Offset;
+ CFI_CODE(unsigned char codeOffset, unsigned char cfiOpcode,
+ short dwarfReg, int offset)
+ : CodeOffset(codeOffset)
+ , CfiOpCode(cfiOpcode)
+ , DwarfReg(dwarfReg)
+ , Offset(offset)
+ {}
+};
+typedef CFI_CODE* PCFI_CODE;
+
+#endif // CFI_H
+
diff --git a/lib/coreclr/src/inc/check.h b/lib/coreclr/src/inc/check.h
new file mode 100644
index 0000000000..a05960f332
--- /dev/null
+++ b/lib/coreclr/src/inc/check.h
@@ -0,0 +1,740 @@
+// 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.
+// ---------------------------------------------------------------------------
+// Check.h
+//
+
+//
+// Assertion checking infrastructure
+// ---------------------------------------------------------------------------
+
+
+#ifndef CHECK_H_
+#define CHECK_H_
+
+#include "static_assert.h"
+#include "daccess.h"
+
+#ifdef _DEBUG
+
+#ifdef _MSC_VER
+// Make sure we can recurse deep enough for FORCEINLINE
+#pragma inline_recursion(on)
+#pragma inline_depth(16)
+#pragma warning(disable:4714)
+#endif // _MSC_VER
+
+#if !defined(DISABLE_CONTRACTS)
+#define CHECK_INVARIANTS 1
+#define VALIDATE_OBJECTS 1
+#endif
+
+#endif // _DEBUG
+
+#if defined(_DEBUG) && !defined(DACCESS_COMPILE)
+#define _DEBUG_IMPL 1
+#endif
+
+#ifdef _DEBUG
+#define DEBUG_ARG(x) , x
+#else
+#define DEBUG_ARG(x)
+#endif
+
+#define CHECK_STRESS 1
+
+//--------------------------------------------------------------------------------
+// A CHECK is an object which encapsulates a potential assertion
+// failure. It not only contains the result of the check, but if the check fails,
+// also records information about the condition and call site.
+//
+// CHECK also serves as a holder to prevent recursive CHECKS. These can be
+// particularly common when putting preconditions inside predicates, especially
+// routines called by an invariant.
+//
+// Note that using CHECK is perfectly efficient in a free build - the CHECK becomes
+// a simple string constant pointer (typically either NULL or (LPCSTR)1, although some
+// check failures may include messages)
+//
+// NOTE: you should NEVER use the CHECK class API directly - use the macros below.
+//--------------------------------------------------------------------------------
+
+class SString;
+
+class CHECK
+{
+protected:
+ // On retail, this is a pointer to a string literal, null or (LPCSTR)1.
+ // On debug, this is a pointer to dynamically allocated memory - that
+ // lets us have formatted strings in debug builds.
+ LPCSTR m_message;
+
+#ifdef _DEBUG
+ LPCSTR m_condition;
+ LPCSTR m_file;
+ INT m_line;
+ LONG *m_pCount;
+
+ // Keep leakage counters.
+ static size_t s_cLeakedBytes;
+ static size_t s_cNumFailures;
+#endif
+
+ static BOOL s_neverEnforceAsserts;
+
+public: // !!! NOTE: Called from macros only!!!
+
+ // If we are not in a check, return TRUE and PushCheck; otherwise return FALSE
+ BOOL EnterAssert();
+
+ // Pops check count
+ void LeaveAssert();
+
+ // Just return if we are in a check
+ BOOL IsInAssert();
+
+ // Should we skip enforcing asserts
+ static BOOL EnforceAssert();
+
+ static BOOL EnforceAssert_StaticCheckOnly();
+
+ static void ResetAssert();
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4702) // Disable bogus unreachable code warning
+#endif // _MSC_VER
+ CHECK() : m_message(NULL)
+#ifdef _DEBUG
+ , m_condition (NULL)
+ , m_file(NULL)
+ , m_line(NULL)
+ , m_pCount(NULL)
+#endif
+ {}
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
+ // Fail records the result of a condition check. Can take either a
+ // boolean value or another check result
+ BOOL Fail(BOOL condition);
+ BOOL Fail(const CHECK &check);
+
+ // Setup records context info after a failure.
+ void Setup(LPCSTR message DEBUG_ARG(LPCSTR condition) DEBUG_ARG(LPCSTR file) DEBUG_ARG(INT line));
+ static LPCSTR FormatMessage(LPCSTR messageFormat, ...);
+
+ // Trigger triggers the actual check failure. The trigger may provide a reason
+ // to include in the failure message.
+ void Trigger(LPCSTR reason);
+
+ // Finally, convert to a BOOL to allow just testing the result of a Check function
+ operator BOOL();
+
+ BOOL operator!();
+
+ CHECK &operator()() { return *this; }
+
+ static inline const CHECK OK() {
+ return CHECK();
+ }
+
+ static void SetAssertEnforcement(BOOL value);
+
+ static void ReleaseTls(void* pCountTLS);
+
+ private:
+ static LONG* InitTls();
+#ifdef _DEBUG
+ static LPCSTR AllocateDynamicMessage(const SString &s);
+#endif
+};
+
+
+//--------------------------------------------------------------------------------
+// These CHECK macros are the correct way to propagate an assertion. These
+// routines are designed for use inside "Check" routines. Such routines may
+// be Invariants, Validate routines, or any other assertional predicates.
+//
+// A Check routine should return a value of type CHECK.
+//
+// It should consist of multiple CHECK or CHECK_MSG statements (along with appropritate
+// control flow) and should end with CHECK_OK() if all other checks pass.
+//
+// It may contain a CONTRACT_CHECK contract, but this is only appropriate if the
+// check is used for non-assertional purposes (otherwise the contract will never execute).
+// Note that CONTRACT_CHECK contracts do not support postconditions.
+//
+// CHECK: Check the given condition, return a CHECK failure if FALSE
+// CHECK_MSG: Same, but include a message paramter if the check fails
+// CHECK_OK: Return a successful check value;
+//--------------------------------------------------------------------------------
+
+#ifdef _DEBUG
+#define DEBUG_ONLY_MESSAGE(msg) msg
+#else
+// On retail, we don't want to add a bunch of string literals to the image,
+// so we just use the same one everywhere.
+#define DEBUG_ONLY_MESSAGE(msg) ((LPCSTR)1)
+#endif
+
+#define CHECK_MSG_EX(_condition, _message, _RESULT) \
+do \
+{ \
+ CHECK _check; \
+ if (_check.Fail(_condition)) \
+ { \
+ ENTER_DEBUG_ONLY_CODE; \
+ _check.Setup(DEBUG_ONLY_MESSAGE(_message) \
+ DEBUG_ARG(#_condition) \
+ DEBUG_ARG(__FILE__) \
+ DEBUG_ARG(__LINE__)); \
+ _RESULT(_check); \
+ LEAVE_DEBUG_ONLY_CODE; \
+ } \
+} while (0)
+
+#define RETURN_RESULT(r) return r
+
+#define CHECK_MSG(_condition, _message) \
+ CHECK_MSG_EX(_condition, _message, RETURN_RESULT)
+
+#define CHECK(_condition) \
+ CHECK_MSG(_condition, "")
+
+#define CHECK_MSGF(_condition, _args) \
+ CHECK_MSG(_condition, CHECK::FormatMessage _args)
+
+#define CHECK_FAIL(_message) \
+ CHECK_MSG(FALSE, _message); UNREACHABLE()
+
+#define CHECK_FAILF(_args) \
+ CHECK_MSGF(FALSE, _args); UNREACHABLE()
+
+#define CHECK_OK \
+ return CHECK::OK()
+
+//--------------------------------------------------------------------------------
+// ASSERT_CHECK is the proper way to trigger a check result. If the CHECK
+// has failed, the diagnostic assertion routines will fire with appropriate
+// context information.
+//
+// Note that the condition may either be a raw boolean expression or a CHECK result
+// returned from a Check routine.
+//
+// Recursion note: ASSERT_CHECKs are only performed if there is no current check in
+// progress.
+//--------------------------------------------------------------------------------
+
+#ifndef ENTER_DEBUG_ONLY_CODE
+#define ENTER_DEBUG_ONLY_CODE
+#endif
+
+#ifndef LEAVE_DEBUG_ONLY_CODE
+#define LEAVE_DEBUG_ONLY_CODE
+#endif
+
+#define ASSERT_CHECK(_condition, _message, _reason) \
+do \
+{ \
+ CHECK _check; \
+ if (_check.EnterAssert()) \
+ { \
+ ENTER_DEBUG_ONLY_CODE; \
+ if (_check.Fail(_condition)) \
+ { \
+ _check.Setup(_message \
+ DEBUG_ARG(#_condition) \
+ DEBUG_ARG(__FILE__) \
+ DEBUG_ARG(__LINE__)); \
+ _check.Trigger(_reason); \
+ } \
+ LEAVE_DEBUG_ONLY_CODE; \
+ _check.LeaveAssert(); \
+ } \
+} while (0)
+
+// ex: ASSERT_CHECKF(1+2==4, "my reason", ("Woah %d", 1+3));
+// note that the double parenthesis, the 'args' param below will include one pair of parens.
+#define ASSERT_CHECKF(_condition, _reason, _args) \
+ ASSERT_CHECK(_condition, CHECK::FormatMessage _args, _reason)
+
+//--------------------------------------------------------------------------------
+// INVARIANTS are descriptions of conditions which are always true at well defined
+// points of execution. Invariants may be checked by the caller or callee at any
+// time as paranoia requires.
+//
+// There are really two flavors of invariant. The "public invariant" describes
+// to the caller invariant behavior about the abstraction which is visible from
+// the public API (and of course it should be expressible in that public API).
+//
+// The "internal invariant" (or representation invariant), on the other hand, is
+// a description of the private implementation of the abstraction, which may examine
+// internal state of the abstraction or use private entry points.
+//
+// Classes with invariants should introduce methods called
+// void Invariant();
+// and
+// void InternalInvariant();
+// to allow invariant checks.
+//--------------------------------------------------------------------------------
+
+#if CHECK_INVARIANTS
+
+template
+CHECK CheckInvariant(TYPENAME &obj)
+{
+#if defined(_MSC_VER) || defined(__llvm__)
+ __if_exists(TYPENAME::Invariant)
+ {
+ CHECK(obj.Invariant());
+ }
+ __if_exists(TYPENAME::InternalInvariant)
+ {
+ CHECK(obj.InternalInvariant());
+ }
+#endif
+
+ CHECK_OK;
+}
+
+#define CHECK_INVARIANT(o) \
+ ASSERT_CHECK(CheckInvariant(o), NULL, "Invariant failure")
+
+#else
+
+#define CHECK_INVARIANT(o) do { } while (0)
+
+#endif
+
+//--------------------------------------------------------------------------------
+// VALIDATE is a check to be made on an object type which identifies a pointer as
+// a valid instance of the object, by calling CheckPointer on it. Normally a null
+// pointer is treated as an error; VALIDATE_NULL (or CheckPointer(o, NULL_OK))
+// may be used when a null pointer is acceptible.
+//
+// In addition to the null/non-null check, a type may provide a specific Check method
+// for more sophisticated identification. In general, the Check method
+// should answer the question
+// "Is this a valid instance of its declared compile-time type?". For instance, if
+// runtype type identification were supported for the type, it should be invoked here.
+//
+// Note that CheckPointer will also check the invariant(s) if appropriate, so the
+// invariants should NOT be explicitly invoked from the Check method.
+//--------------------------------------------------------------------------------
+
+enum IsNullOK
+{
+ NULL_NOT_OK = 0,
+ NULL_OK = 1
+};
+
+#if CHECK_INVARIANTS
+template
+CHECK CheckPointer(TYPENAME *o, IsNullOK ok = NULL_NOT_OK)
+{
+ if (o == NULL)
+ {
+ CHECK_MSG(ok, "Illegal null pointer");
+ }
+ else
+ {
+#if defined(_MSC_VER) || defined(__llvm__)
+ __if_exists(TYPENAME::Check)
+ {
+ CHECK(o->Check());
+ }
+#endif
+ }
+
+ CHECK_OK;
+}
+
+template
+CHECK CheckValue(TYPENAME &val)
+{
+#if defined(_MSC_VER) || defined(__llvm__)
+ __if_exists(TYPENAME::Check)
+ {
+ CHECK(val.Check());
+ }
+#endif
+
+ CHECK(CheckInvariant(val));
+
+ CHECK_OK;
+}
+#else // CHECK_INVARIANTS
+
+#ifdef _DEBUG_IMPL
+// Don't defined these functions to be nops for the non-debug
+// build as it may hide important checks
+template
+CHECK CheckPointer(TYPENAME *o, IsNullOK ok = NULL_NOT_OK)
+{
+ if (o == NULL)
+ {
+ CHECK_MSG(ok, "Illegal null pointer");
+ }
+
+ CHECK_OK;
+}
+
+template
+CHECK CheckValue(TYPENAME &val)
+{
+ CHECK_OK;
+}
+#endif
+
+#endif // CHECK_INVARIANTS
+
+#if VALIDATE_OBJECTS
+
+#define VALIDATE(o) \
+ ASSERT_CHECK(CheckPointer(o), "Validation failure")
+#define VALIDATE_NULL(o) \
+ ASSERT_CHECK(CheckPointer(o, NULL_OK), "Validation failure")
+
+#else
+
+#define VALIDATE(o) do { } while (0)
+#define VALIDATE_NULL(o) do { } while (0)
+
+#endif
+
+//--------------------------------------------------------------------------------
+// CONSISTENCY_CHECKS are ad-hoc assertions about the expected state of the program
+// at a given time. A failure in one of these indicates a bug in the code.
+//
+// Note that the condition may either be a raw boolean expression or a CHECK result
+// returned from a Check routine.
+//--------------------------------------------------------------------------------
+
+#define CONSISTENCY_CHECK(_condition) \
+ CONSISTENCY_CHECK_MSG(_condition, "")
+
+#ifdef _DEBUG_IMPL
+
+#define CONSISTENCY_CHECK_MSG(_condition, _message) \
+ ASSERT_CHECK(_condition, _message, "Consistency check failed")
+
+#define CONSISTENCY_CHECK_MSGF(_condition, args) \
+ ASSERT_CHECKF(_condition, "Consistency check failed", args)
+
+#else
+
+#define CONSISTENCY_CHECK_MSG(_condition, _message) do { } while (0)
+#define CONSISTENCY_CHECK_MSGF(_condition, args) do { } while (0)
+
+#endif
+
+//--------------------------------------------------------------------------------
+// SIMPLIFYING_ASSUMPTIONS are workarounds which are placed in the code to allow progress
+// to be made in the case of difficult corner cases. These should NOT be left in the
+// code; they are really just markers of things which need to be fixed.
+//
+// Note that the condition may either be a raw boolean expression or a CHECK result
+// returned from a Check routine.
+//--------------------------------------------------------------------------------
+
+// Ex usage:
+// SIMPLIFYING_ASSUMPTION(SomeExpression());
+#define SIMPLIFYING_ASSUMPTION(_condition) \
+ SIMPLIFYING_ASSUMPTION_MSG(_condition, "")
+
+
+// Helper for HRs. Will provide formatted message showing the failure code.
+#define SIMPLIFYING_ASSUMPTION_SUCCEEDED(__hr) \
+ { \
+ HRESULT __hr2 = (__hr); \
+ (void)__hr2; \
+ SIMPLIFYING_ASSUMPTION_MSGF(SUCCEEDED(__hr2), ("HRESULT failed.\n Expected success.\n Actual=0x%x\n", __hr2)); \
+ }
+
+#ifdef _DEBUG_IMPL
+
+// Ex usage:
+// SIMPLIFYING_ASSUMPTION_MSG(SUCCEEDED(hr), "It failed!");
+#define SIMPLIFYING_ASSUMPTION_MSG(_condition, _message) \
+ ASSERT_CHECK(_condition, _message, "Unhandled special case detected")
+
+// use a formatted string. Ex usage:
+// SIMPLIFYING_ASSUMPTION_MSGF(SUCCEEDED(hr), ("Woah it failed! 0x%08x", hr));
+#define SIMPLIFYING_ASSUMPTION_MSGF(_condition, args) \
+ ASSERT_CHECKF(_condition, "Unhandled special case detected", args)
+
+#else // !_DEBUG_IMPL
+
+#define SIMPLIFYING_ASSUMPTION_MSG(_condition, _message) do { } while (0)
+#define SIMPLIFYING_ASSUMPTION_MSGF(_condition, args) do { } while (0)
+
+#endif // !_DEBUG_IMPL
+
+//--------------------------------------------------------------------------------
+// COMPILER_ASSUME_MSG is a statement that tells the compiler to assume the
+// condition is true. In a checked build these turn into asserts;
+// in a free build they are passed through to the compiler to use in optimization.
+//--------------------------------------------------------------------------------
+
+#if defined(_PREFAST_) || defined(_PREFIX_) || defined(__clang_analyzer__)
+#define COMPILER_ASSUME_MSG(_condition, _message) if (!(_condition)) __UNREACHABLE();
+#define COMPILER_ASSUME_MSGF(_condition, args) if (!(_condition)) __UNREACHABLE();
+#else
+
+#if defined(DACCESS_COMPILE)
+#define COMPILER_ASSUME_MSG(_condition, _message) do { } while (0)
+#define COMPILER_ASSUME_MSGF(_condition, args) do { } while (0)
+#else
+
+#if defined(_DEBUG)
+#define COMPILER_ASSUME_MSG(_condition, _message) \
+ ASSERT_CHECK(_condition, _message, "Compiler optimization assumption invalid")
+#define COMPILER_ASSUME_MSGF(_condition, args) \
+ ASSERT_CHECKF(_condition, "Compiler optimization assumption invalid", args)
+#else
+#define COMPILER_ASSUME_MSG(_condition, _message) __assume(_condition)
+#define COMPILER_ASSUME_MSGF(_condition, args) __assume(_condition)
+#endif // _DEBUG
+
+#endif // DACCESS_COMPILE
+
+#endif // _PREFAST_ || _PREFIX_
+
+
+#define COMPILER_ASSUME(_condition) \
+ COMPILER_ASSUME_MSG(_condition, "")
+
+
+//--------------------------------------------------------------------------------
+// PREFIX_ASSUME_MSG and PREFAST_ASSUME_MSG are just another name
+// for COMPILER_ASSUME_MSG
+// In a checked build these turn into asserts; in a free build
+// they are passed through to the compiler to use in optimization;
+// via an __assume(_condition) optimization hint.
+//--------------------------------------------------------------------------------
+
+#define PREFIX_ASSUME_MSG(_condition, _message) \
+ COMPILER_ASSUME_MSG(_condition, _message)
+
+#define PREFIX_ASSUME_MSGF(_condition, args) \
+ COMPILER_ASSUME_MSGF(_condition, args)
+
+#define PREFIX_ASSUME(_condition) \
+ COMPILER_ASSUME_MSG(_condition, "")
+
+#define PREFAST_ASSUME_MSG(_condition, _message) \
+ COMPILER_ASSUME_MSG(_condition, _message)
+
+#define PREFAST_ASSUME_MSGF(_condition, args) \
+ COMPILER_ASSUME_MSGF(_condition, args)
+
+#define PREFAST_ASSUME(_condition) \
+ COMPILER_ASSUME_MSG(_condition, "")
+
+//--------------------------------------------------------------------------------
+// UNREACHABLE points are locations in the code which should not be able to be
+// reached under any circumstances (e.g. a default in a switch which is supposed to
+// cover all cases.). This macro tells the compiler this, and also embeds a check
+// to make sure it is always true.
+//--------------------------------------------------------------------------------
+
+#define UNREACHABLE() \
+ UNREACHABLE_MSG("")
+
+#ifdef __llvm__
+
+// LLVM complains if a function does not return what it says.
+#define UNREACHABLE_RET() do { UNREACHABLE(); return 0; } while (0)
+#define UNREACHABLE_MSG_RET(_message) UNREACHABLE_MSG(_message); return 0;
+
+#else // __llvm__
+
+#define UNREACHABLE_RET() UNREACHABLE()
+#define UNREACHABLE_MSG_RET(_message) UNREACHABLE_MSG(_message)
+
+#endif // __llvm__ else
+
+#if defined(_MSC_VER) || defined(_PREFIX_)
+#if defined(_TARGET_AMD64_)
+// Empty methods that consist of UNREACHABLE() result in a zero-sized declspec(noreturn) method
+// which causes the pdb file to make the next method declspec(noreturn) as well, thus breaking BBT
+// Remove when we get a VC compiler that fixes VSW 449170
+# define __UNREACHABLE() DebugBreak(); __assume(0);
+#else
+# define __UNREACHABLE() __assume(0)
+#endif
+#else
+#define __UNREACHABLE() __builtin_unreachable()
+#endif
+
+#ifdef _DEBUG_IMPL
+
+// Note that the "do { } while (0)" syntax trick here doesn't work, as the compiler
+// gives an error that the while(0) is unreachable code
+#define UNREACHABLE_MSG(_message) \
+{ \
+ CHECK _check; \
+ _check.Setup(_message, "", __FILE__, __LINE__); \
+ _check.Trigger("Reached the \"unreachable\""); \
+} __UNREACHABLE()
+
+#else
+
+#define UNREACHABLE_MSG(_message) __UNREACHABLE()
+
+#endif
+
+
+//--------------------------------------------------------------------------------
+// STRESS_CHECK represents a check which is included in a free build
+// @todo: behavior on trigger
+//
+// Note that the condition may either be a raw boolean expression or a CHECK result
+// returned from a Check routine.
+//
+// Since Retail builds don't allow formatted checks, there's no STRESS_CHECK_MSGF.
+//--------------------------------------------------------------------------------
+
+#if CHECK_STRESS
+
+#define STRESS_CHECK(_condition, _message) \
+ ASSERT_CHECK(_condition, _message, "Stress Assertion Failure")
+
+#else
+
+#define STRESS_CHECK(_condition, _message) do { } while (0)
+
+#endif
+
+//--------------------------------------------------------------------------------
+// CONTRACT_CHECK is used to put contracts on Check function. Note that it does
+// not support postconditions.
+//--------------------------------------------------------------------------------
+
+#define CONTRACT_CHECK CONTRACTL
+#define CONTRACT_CHECK_END CONTRACTL_END
+
+//--------------------------------------------------------------------------------
+// CCHECK is used for Check functions which may fail due to out of memory
+// or other transient failures. These failures should be ignored when doing
+// assertions, but they cannot be ignored when the Check function is used in
+// normal code.
+// @todo: really crufty to have 2 sets of CHECK macros
+//--------------------------------------------------------------------------------
+
+#ifdef _DEBUG
+
+#define CCHECK_START \
+ { \
+ BOOL ___exception = FALSE; \
+ BOOL ___transient = FALSE; \
+ CHECK ___result = CHECK::OK(); \
+ EX_TRY {
+
+#define CCHECK_END \
+ } EX_CATCH { \
+ if (___result.IsInAssert()) \
+ { \
+ ___exception = TRUE; \
+ ___transient = GET_EXCEPTION()->IsTransient(); \
+ } \
+ else \
+ EX_RETHROW; \
+ } EX_END_CATCH(RethrowTerminalExceptions); \
+ \
+ if (___exception) \
+ { \
+ if (___transient) \
+ CHECK_OK; \
+ else \
+ CHECK_FAIL("Nontransient exception occurred during check"); \
+ } \
+ CHECK(___result); \
+ }
+
+#define CRETURN_RESULT(r) ___result = r
+
+#define CCHECK_MSG(_condition, _message) \
+ CHECK_MSG_EX(_condition, _message, CRETURN_RESULT)
+
+#define CCHECK(_condition) \
+ CCHECK_MSG(_condition, "")
+
+#define CCHECK_MSGF(_condition, _args) \
+ CCHECK_MSG(_condition, CHECK::FormatMessage _args)
+
+#define CCHECK_FAIL(_message) \
+ CCHECK_MSG(FALSE, _message); UNREACHABLE()
+
+#define CCHECK_FAILF(_args) \
+ CCHECK_MSGF(FALSE, _args); UNREACHABLE()
+
+#else // _DEBUG
+
+#define CCHECK_START
+#define CCHECK_END
+
+#define CCHECK CHECK
+#define CCHECK_MSG CHECK_MSG
+#define CCHECK_MSGF CHECK_MSGF
+#define CCHECK_FAIL CHECK_FAIL
+#define CCHECK_FAILF CHECK_FAILF
+
+#endif
+
+
+
+//--------------------------------------------------------------------------------
+// Common base level checks
+//--------------------------------------------------------------------------------
+
+CHECK CheckAlignment(UINT alignment);
+
+CHECK CheckAligned(UINT value, UINT alignment);
+#if defined(_MSC_VER)
+CHECK CheckAligned(ULONG value, UINT alignment);
+#endif
+CHECK CheckAligned(UINT64 value, UINT alignment);
+CHECK CheckAligned(const void *address, UINT alignment);
+
+CHECK CheckOverflow(UINT value1, UINT value2);
+#if defined(_MSC_VER)
+CHECK CheckOverflow(ULONG value1, ULONG value2);
+#endif
+CHECK CheckOverflow(UINT64 value1, UINT64 value2);
+CHECK CheckOverflow(PTR_CVOID address, UINT offset);
+#if defined(_MSC_VER)
+CHECK CheckOverflow(const void *address, ULONG offset);
+#endif
+CHECK CheckOverflow(const void *address, UINT64 offset);
+
+CHECK CheckUnderflow(UINT value1, UINT value2);
+#if defined(_MSC_VER)
+CHECK CheckUnderflow(ULONG value1, ULONG value2);
+#endif
+CHECK CheckUnderflow(UINT64 value1, UINT64 value2);
+CHECK CheckUnderflow(const void *address, UINT offset);
+#if defined(_MSC_VER)
+CHECK CheckUnderflow(const void *address, ULONG offset);
+#endif
+CHECK CheckUnderflow(const void *address, UINT64 offset);
+CHECK CheckUnderflow(const void *address, void *address2);
+
+CHECK CheckZeroedMemory(const void *memory, SIZE_T size);
+
+// These include overflow checks
+CHECK CheckBounds(const void *rangeBase, UINT32 rangeSize, UINT32 offset);
+CHECK CheckBounds(const void *rangeBase, UINT32 rangeSize, UINT32 offset, UINT32 size);
+
+void WINAPI ReleaseCheckTls(LPVOID pTlsData);
+
+// ================================================================================
+// Inline definitions
+// ================================================================================
+
+#include "check.inl"
+
+#endif // CHECK_H_
diff --git a/lib/coreclr/src/inc/check.inl b/lib/coreclr/src/inc/check.inl
new file mode 100644
index 0000000000..9a3597ef81
--- /dev/null
+++ b/lib/coreclr/src/inc/check.inl
@@ -0,0 +1,367 @@
+// 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.
+
+#ifndef CHECK_INL_
+#define CHECK_INL_
+
+#include "check.h"
+#include "clrhost.h"
+#include "debugmacros.h"
+#include "clrtypes.h"
+
+inline LONG *CHECK::InitTls()
+{
+#pragma push_macro("HeapAlloc")
+#pragma push_macro("GetProcessHeap")
+#undef HeapAlloc
+#undef GetProcessHeap
+
+ LONG *pCount = (LONG *)::HeapAlloc(GetProcessHeap(), 0, sizeof(LONG));
+ if (pCount)
+ *pCount = 0;
+
+#pragma pop_macro("HeapAlloc")
+#pragma pop_macro("GetProcessHeap")
+ ClrFlsSetValue(TlsIdx_Check, pCount);
+ ClrFlsAssociateCallback(TlsIdx_Check, ReleaseCheckTls);
+ return pCount;
+}
+
+inline void CHECK::ReleaseTls(void* pCountTLS)
+{
+#pragma push_macro("HeapFree")
+#pragma push_macro("GetProcessHeap")
+#undef HeapFree
+#undef GetProcessHeap
+ LONG* pCount = (LONG*) pCountTLS;
+ if (pCount)
+ ::HeapFree(GetProcessHeap(), 0, pCount);
+
+#pragma pop_macro("HeapFree")
+#pragma pop_macro("GetProcessHeap")
+}
+
+FORCEINLINE BOOL CHECK::EnterAssert()
+{
+ if (s_neverEnforceAsserts)
+ return FALSE;
+
+#ifdef _DEBUG_IMPL
+ m_pCount = (LONG *)ClrFlsGetValue(TlsIdx_Check);
+ if (!m_pCount)
+ {
+ m_pCount = InitTls();
+ if (!m_pCount)
+ return FALSE;
+ }
+
+ if (!*m_pCount)
+ {
+ *m_pCount = 1;
+ return TRUE;
+ }
+ else
+ return FALSE;
+#else
+ // Don't bother doing recursive checks on a free build, since checks should
+ // be extremely isolated
+ return TRUE;
+#endif
+}
+
+FORCEINLINE void CHECK::LeaveAssert()
+{
+#ifdef _DEBUG_IMPL
+ *m_pCount = 0;
+#endif
+}
+
+FORCEINLINE BOOL CHECK::IsInAssert()
+{
+#ifdef _DEBUG_IMPL
+ if (!m_pCount)
+ m_pCount = (LONG *)ClrFlsGetValue(TlsIdx_Check);
+
+ if (!m_pCount)
+ return FALSE;
+ else
+ return *m_pCount;
+#else
+ return FALSE;
+#endif
+}
+
+FORCEINLINE BOOL CHECK::EnforceAssert()
+{
+ if (s_neverEnforceAsserts)
+ return FALSE;
+ else
+ {
+ CHECK chk;
+ return !chk.IsInAssert();
+ }
+}
+
+FORCEINLINE void CHECK::ResetAssert()
+{
+ CHECK chk;
+ if (chk.IsInAssert())
+ chk.LeaveAssert();
+}
+
+inline void CHECK::SetAssertEnforcement(BOOL value)
+{
+ s_neverEnforceAsserts = !value;
+}
+
+// Fail records the result of a condition check. Can take either a
+// boolean value or another check result
+FORCEINLINE BOOL CHECK::Fail(BOOL condition)
+{
+#ifdef _DEBUG
+ if (!condition)
+ {
+ m_condition = NULL;
+ m_file = NULL;
+ m_line = 0;
+ }
+#endif
+ return !condition;
+}
+
+FORCEINLINE BOOL CHECK::Fail(const CHECK &check)
+{
+ m_message = check.m_message;
+#ifdef _DEBUG
+ if (m_message != NULL)
+ {
+ m_condition = check.m_condition;
+ m_file = check.m_file;
+ m_line = check.m_line;
+ }
+#endif
+ return m_message != NULL;
+}
+
+#ifndef _DEBUG
+FORCEINLINE void CHECK::Setup(LPCSTR message)
+{
+ m_message = message;
+}
+
+FORCEINLINE LPCSTR CHECK::FormatMessage(LPCSTR messageFormat, ...)
+{
+ return messageFormat;
+}
+#endif
+
+FORCEINLINE CHECK::operator BOOL ()
+{
+ return m_message == NULL;
+}
+
+FORCEINLINE BOOL CHECK::operator!()
+{
+ return m_message != NULL;
+}
+
+inline CHECK CheckAlignment(UINT alignment)
+{
+ STATIC_CONTRACT_WRAPPER;
+ CHECK((alignment & (alignment-1)) == 0);
+ CHECK_OK;
+}
+
+inline CHECK CheckAligned(UINT value, UINT alignment)
+{
+ STATIC_CONTRACT_WRAPPER;
+ CHECK(AlignmentTrim(value, alignment) == 0);
+ CHECK_OK;
+}
+
+#ifndef PLATFORM_UNIX
+// For Unix this and the previous function get the same types.
+// So, exclude this one.
+inline CHECK CheckAligned(ULONG value, UINT alignment)
+{
+ STATIC_CONTRACT_WRAPPER;
+ CHECK(AlignmentTrim(value, alignment) == 0);
+ CHECK_OK;
+}
+#endif // PLATFORM_UNIX
+
+inline CHECK CheckAligned(UINT64 value, UINT alignment)
+{
+ STATIC_CONTRACT_WRAPPER;
+ CHECK(AlignmentTrim(value, alignment) == 0);
+ CHECK_OK;
+}
+
+inline CHECK CheckAligned(const void *address, UINT alignment)
+{
+ STATIC_CONTRACT_WRAPPER;
+ CHECK(AlignmentTrim((SIZE_T)address, alignment) == 0);
+ CHECK_OK;
+}
+
+inline CHECK CheckOverflow(UINT value1, UINT value2)
+{
+ CHECK(value1 + value2 >= value1);
+ CHECK_OK;
+}
+
+#if defined(_MSC_VER)
+inline CHECK CheckOverflow(ULONG value1, ULONG value2)
+{
+ CHECK(value1 + value2 >= value1);
+ CHECK_OK;
+}
+#endif
+
+inline CHECK CheckOverflow(UINT64 value1, UINT64 value2)
+{
+ CHECK(value1 + value2 >= value1);
+ CHECK_OK;
+}
+
+inline CHECK CheckOverflow(PTR_CVOID address, UINT offset)
+{
+ TADDR targetAddr = dac_cast(address);
+#if POINTER_BITS == 32
+ CHECK((UINT) (SIZE_T)(targetAddr) + offset >= (UINT) (SIZE_T) (targetAddr));
+#else
+ CHECK((UINT64) targetAddr + offset >= (UINT64) targetAddr);
+#endif
+
+ CHECK_OK;
+}
+
+#if defined(_MSC_VER)
+inline CHECK CheckOverflow(const void *address, ULONG offset)
+{
+#if POINTER_BITS == 32
+ CHECK((ULONG) (SIZE_T) address + offset >= (ULONG) (SIZE_T) address);
+#else
+ CHECK((UINT64) address + offset >= (UINT64) address);
+#endif
+
+ CHECK_OK;
+}
+#endif
+
+inline CHECK CheckOverflow(const void *address, UINT64 offset)
+{
+#if POINTER_BITS == 32
+ CHECK(offset >> 32 == 0);
+ CHECK((UINT) (SIZE_T) address + (UINT) offset >= (UINT) (SIZE_T) address);
+#else
+ CHECK((UINT64) address + offset >= (UINT64) address);
+#endif
+
+ CHECK_OK;
+}
+
+
+inline CHECK CheckUnderflow(UINT value1, UINT value2)
+{
+ CHECK(value1 - value2 <= value1);
+
+ CHECK_OK;
+}
+
+#ifndef PLATFORM_UNIX
+// For Unix this and the previous function get the same types.
+// So, exclude this one.
+inline CHECK CheckUnderflow(ULONG value1, ULONG value2)
+{
+ CHECK(value1 - value2 <= value1);
+
+ CHECK_OK;
+}
+#endif // PLATFORM_UNIX
+
+inline CHECK CheckUnderflow(UINT64 value1, UINT64 value2)
+{
+ CHECK(value1 - value2 <= value1);
+
+ CHECK_OK;
+}
+
+inline CHECK CheckUnderflow(const void *address, UINT offset)
+{
+#if POINTER_BITS == 32
+ CHECK((UINT) (SIZE_T) address - offset <= (UINT) (SIZE_T) address);
+#else
+ CHECK((UINT64) address - offset <= (UINT64) address);
+#endif
+
+ CHECK_OK;
+}
+
+#if defined(_MSC_VER)
+inline CHECK CheckUnderflow(const void *address, ULONG offset)
+{
+#if POINTER_BITS == 32
+ CHECK((ULONG) (SIZE_T) address - offset <= (ULONG) (SIZE_T) address);
+#else
+ CHECK((UINT64) address - offset <= (UINT64) address);
+#endif
+
+ CHECK_OK;
+}
+#endif
+
+inline CHECK CheckUnderflow(const void *address, UINT64 offset)
+{
+#if POINTER_BITS == 32
+ CHECK(offset >> 32 == 0);
+ CHECK((UINT) (SIZE_T) address - (UINT) offset <= (UINT) (SIZE_T) address);
+#else
+ CHECK((UINT64) address - offset <= (UINT64) address);
+#endif
+
+ CHECK_OK;
+}
+
+inline CHECK CheckUnderflow(const void *address, void *address2)
+{
+#if POINTER_BITS == 32
+ CHECK((UINT) (SIZE_T) address - (UINT) (SIZE_T) address2 <= (UINT) (SIZE_T) address);
+#else
+ CHECK((UINT64) address - (UINT64) address2 <= (UINT64) address);
+#endif
+
+ CHECK_OK;
+}
+
+inline CHECK CheckZeroedMemory(const void *memory, SIZE_T size)
+{
+ CHECK(CheckOverflow(memory, size));
+
+ BYTE *p = (BYTE *) memory;
+ BYTE *pEnd = p + size;
+
+ while (p < pEnd)
+ CHECK(*p++ == 0);
+
+ CHECK_OK;
+}
+
+inline CHECK CheckBounds(const void *rangeBase, UINT32 rangeSize, UINT32 offset)
+{
+ CHECK(CheckOverflow(dac_cast(rangeBase), rangeSize));
+ CHECK(offset <= rangeSize);
+ CHECK_OK;
+}
+
+inline CHECK CheckBounds(const void *rangeBase, UINT32 rangeSize, UINT32 offset, UINT32 size)
+{
+ CHECK(CheckOverflow(dac_cast(rangeBase), rangeSize));
+ CHECK(CheckOverflow(offset, size));
+ CHECK(offset + size <= rangeSize);
+ CHECK_OK;
+}
+
+#endif // CHECK_INL_
+
diff --git a/lib/coreclr/src/inc/circularlog.h b/lib/coreclr/src/inc/circularlog.h
new file mode 100644
index 0000000000..4ee8d2fa99
--- /dev/null
+++ b/lib/coreclr/src/inc/circularlog.h
@@ -0,0 +1,38 @@
+// 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.
+
+
+#ifndef _CIRCULARLOG_H__
+
+#define _CIRCULARLOG_H__
+
+#include "sstring.h"
+
+class CircularLog
+{
+public:
+ CircularLog();
+ ~CircularLog();
+
+ bool Init(const WCHAR* logname, const WCHAR* logHeader, DWORD maxSize = 1024*1024);
+ void Shutdown();
+ void Log(const WCHAR* string);
+
+protected:
+
+ void CheckForLogReset(BOOL fOverflow);
+ BOOL CheckLogHeader();
+ HANDLE OpenFile();
+ void CloseFile();
+
+ bool m_bInit;
+ SString m_LogFilename;
+ SString m_LogHeader;
+ SString m_OldLogFilename;
+ SString m_LockFilename;
+ DWORD m_MaxSize;
+ unsigned m_uLogCount;
+};
+
+#endif
diff --git a/lib/coreclr/src/inc/clr/fs.h b/lib/coreclr/src/inc/clr/fs.h
new file mode 100644
index 0000000000..d6bcb75309
--- /dev/null
+++ b/lib/coreclr/src/inc/clr/fs.h
@@ -0,0 +1,16 @@
+// 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 header will include all headers relating to file system functionality.
+
+#ifndef _clr_fs_h_
+#define _clr_fs_h_
+
+#include "fs/path.h"
+#include "fs/file.h"
+#include "fs/dir.h"
+
+#endif // _clr_fs_h_
diff --git a/lib/coreclr/src/inc/clr/fs/dir.h b/lib/coreclr/src/inc/clr/fs/dir.h
new file mode 100644
index 0000000000..2516151a55
--- /dev/null
+++ b/lib/coreclr/src/inc/clr/fs/dir.h
@@ -0,0 +1,129 @@
+// 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 header provides general directory-related file system services.
+
+#ifndef _clr_fs_Dir_h_
+#define _clr_fs_Dir_h_
+
+#include "clrtypes.h"
+#include "clr/str.h"
+#include "strsafe.h"
+
+#ifndef countof
+ #define countof(x) (sizeof(x) / sizeof(x[0]))
+#endif // !countof
+
+namespace clr
+{
+ namespace fs
+ {
+ class Dir
+ {
+ public:
+ static inline bool Exists(
+ LPCWSTR wzDirPath)
+ {
+ DWORD attrs = WszGetFileAttributes(wzDirPath);
+ return (attrs != INVALID_FILE_ATTRIBUTES) && (attrs & FILE_ATTRIBUTE_DIRECTORY);
+ }
+
+ //-----------------------------------------------------------------------------------------
+ // Creates new directory indicated by wzDirPath.
+ //
+ // Returns:
+ // S_OK - on success directory creation
+ // S_FALSE - when directory previously existed
+ // HR(ERROR_PATH_NOT_FOUND) - when creation of dir fails.
+ static inline HRESULT Create(
+ LPCWSTR wzDirPath)
+ {
+ HRESULT hr = S_OK;
+
+ if (!WszCreateDirectory(wzDirPath, nullptr))
+ {
+ hr = HRESULT_FROM_GetLastError();
+ if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS))
+ {
+ hr = S_FALSE;
+ }
+ }
+ return hr;
+ }
+
+ //-----------------------------------------------------------------------------------------
+ // Creates the specified directory and all required subdirectories. wzDirPath will be
+ // temporarily modified in the process.
+ //
+ // Returns:
+ // S_OK - on success directory creation
+ // S_FALSE - when directory previously existed
+ // HR(ERROR_PATH_NOT_FOUND) - when creation of any dir fails.
+ static inline HRESULT CreateRecursively(
+ __inout_z LPWSTR wzDirPath,
+ size_t cchDirPath = 0)
+ {
+ HRESULT hr = S_OK;
+
+ if (wzDirPath == nullptr)
+ {
+ return E_POINTER;
+ }
+
+ if (cchDirPath == 0)
+ {
+ cchDirPath = wcslen(wzDirPath);
+ }
+
+ // Try to create the path. If it fails, assume that's because the parent folder does
+ // not exist. Try to create the parent then re-attempt.
+ WCHAR chOrig = wzDirPath[cchDirPath];
+ hr = Create(wzDirPath);
+ if (hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND))
+ {
+ for (WCHAR* pCurCh = wzDirPath + cchDirPath - 1; pCurCh != wzDirPath; --pCurCh)
+ {
+ if (*pCurCh == W('\\') || *pCurCh == W('\0'))
+ {
+ WCHAR chOrig = *pCurCh;
+ *pCurCh = W('\0');
+ IfFailRet(CreateRecursively(wzDirPath, pCurCh - wzDirPath));
+ *pCurCh = chOrig;
+ break;
+ }
+ }
+ IfFailRet(Create(wzDirPath));
+ }
+
+ return hr;
+ }
+
+ //-----------------------------------------------------------------------------------------
+ // Creates the specified directory and all required subdirectories.
+ static inline HRESULT CreateRecursively(
+ LPCWSTR wzDirPath)
+ {
+ HRESULT hr = S_OK;
+
+ if (wzDirPath == nullptr)
+ {
+ return E_POINTER;
+ }
+
+ // Make a writable copy of wzDirPath
+ size_t cchDirPath = wcslen(wzDirPath);
+ CQuickWSTR wzBuffer;
+ IfFailRet(wzBuffer.ReSizeNoThrow(cchDirPath + 1));
+ wcscpy_s(wzBuffer.Ptr(), wzBuffer.Size(), wzDirPath);
+ IfFailRet(CreateRecursively(wzBuffer.Ptr(), cchDirPath));
+
+ return hr;
+ }
+ };
+ }
+}
+
+#endif // _clr_fs_Dir_h_
diff --git a/lib/coreclr/src/inc/clr/fs/file.h b/lib/coreclr/src/inc/clr/fs/file.h
new file mode 100644
index 0000000000..70f22a29fa
--- /dev/null
+++ b/lib/coreclr/src/inc/clr/fs/file.h
@@ -0,0 +1,40 @@
+// 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 header provides general filename-related file system services.
+
+#ifndef _clr_fs_File_h_
+#define _clr_fs_File_h_
+
+#include "clrtypes.h"
+#include "cor.h" // SELECTANY
+
+namespace clr
+{
+ namespace fs
+ {
+ // This list taken from ndp/clr/src/bcl/system/io/path.cs
+ SELECTANY WCHAR const g_rgInvalidFileNameChars[] =
+ { W('"'), W('<'), W('>'), W('|'), W('\0'), (WCHAR)1, (WCHAR)2, (WCHAR)3, (WCHAR)4, (WCHAR)5, (WCHAR)6,
+ (WCHAR)7, (WCHAR)8, (WCHAR)9, (WCHAR)10, (WCHAR)11, (WCHAR)12, (WCHAR)13, (WCHAR)14,
+ (WCHAR)15, (WCHAR)16, (WCHAR)17, (WCHAR)18, (WCHAR)19, (WCHAR)20, (WCHAR)21, (WCHAR)22,
+ (WCHAR)23, (WCHAR)24, (WCHAR)25, (WCHAR)26, (WCHAR)27, (WCHAR)28, (WCHAR)29, (WCHAR)30,
+ (WCHAR)31, W(':'), W('*'), W('?'), W('\\'), W('/') };
+
+ class File
+ {
+ public:
+ static inline bool Exists(
+ LPCWSTR wzFilePath)
+ {
+ DWORD attrs = WszGetFileAttributes(wzFilePath);
+ return (attrs != INVALID_FILE_ATTRIBUTES) && !(attrs & FILE_ATTRIBUTE_DIRECTORY);
+ }
+ };
+ }
+}
+
+#endif // _clr_fs_File_h_
diff --git a/lib/coreclr/src/inc/clr/fs/path.h b/lib/coreclr/src/inc/clr/fs/path.h
new file mode 100644
index 0000000000..7c1995ecb2
--- /dev/null
+++ b/lib/coreclr/src/inc/clr/fs/path.h
@@ -0,0 +1,141 @@
+// 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 header provides general path-related file system services.
+
+#ifndef _clr_fs_Path_h_
+#define _clr_fs_Path_h_
+
+#include "clrtypes.h"
+#include "cor.h" // SELECTANY
+
+#include "strsafe.h"
+
+#include "clr/str.h"
+
+#ifndef LONG_FORMAT_PATH_PREFIX
+ #define LONG_FORMAT_PATH_PREFIX W("\\\\?\\")
+#endif
+
+namespace clr
+{
+ namespace fs
+ {
+ // This list taken from ndp/clr/src/bcl/system/io/path.cs
+ SELECTANY WCHAR const g_rgInvalidPathChars[] =
+ { W('"'), W('<'), W('>'), W('|'), W('\0'), (WCHAR)1, (WCHAR)2, (WCHAR)3, (WCHAR)4, (WCHAR)5, (WCHAR)6,
+ (WCHAR)7, (WCHAR)8, (WCHAR)9, (WCHAR)10, (WCHAR)11, (WCHAR)12, (WCHAR)13, (WCHAR)14,
+ (WCHAR)15, (WCHAR)16, (WCHAR)17, (WCHAR)18, (WCHAR)19, (WCHAR)20, (WCHAR)21, (WCHAR)22,
+ (WCHAR)23, (WCHAR)24, (WCHAR)25, (WCHAR)26, (WCHAR)27, (WCHAR)28, (WCHAR)29, (WCHAR)30,
+ (WCHAR)31 };
+
+ class Path
+ {
+ public:
+ //-----------------------------------------------------------------------------------------
+ static inline bool
+ Exists(
+ LPCWSTR wzPath)
+ {
+ DWORD attrs = WszGetFileAttributes(wzPath);
+ return (attrs != INVALID_FILE_ATTRIBUTES);
+ }
+
+ //-----------------------------------------------------------------------------------------
+ // Returns true if wzPath represents a long format path (i.e., prefixed with '\\?\').
+ static inline bool
+ HasLongFormatPrefix(LPCWSTR wzPath)
+ {
+ _ASSERTE(!clr::str::IsNullOrEmpty(wzPath)); // Must check this first.
+ return wcscmp(wzPath, LONG_FORMAT_PATH_PREFIX) == 0;
+ }
+
+ //-----------------------------------------------------------------------------------------
+ // Returns true if wzPath represents a relative path.
+ static inline bool
+ IsRelative(LPCWSTR wzPath)
+ {
+ _ASSERTE(wzPath != nullptr);
+
+ // Similar to System.IO.Path.IsRelative()
+#if PLATFORM_UNIX
+ if(wzPath[0] == VOLUME_SEPARATOR_CHAR_W)
+ {
+ return false;
+ }
+#else
+ // Check for a paths like "C:\..." or "\\...". Additional notes:
+ // - "\\?\..." - long format paths are considered as absolute paths due to the "\\" prefix
+ // - "\..." - these paths are relative, as they depend on the current drive
+ // - "C:..." and not "C:\..." - these paths are relative, as they depend on the current directory for drive C
+ if (wzPath[0] != W('\0') &&
+ wzPath[1] == VOLUME_SEPARATOR_CHAR_W &&
+ wzPath[2] == DIRECTORY_SEPARATOR_CHAR_W &&
+ (
+ (wzPath[0] >= W('A') && wzPath[0] <= W('Z')) ||
+ (wzPath[0] >= W('a') && wzPath[0] <= W('z'))
+ ))
+ {
+ return false;
+ }
+ if (wzPath[0] == DIRECTORY_SEPARATOR_CHAR_W && wzPath[1] == DIRECTORY_SEPARATOR_CHAR_W)
+ {
+ return false;
+ }
+#endif
+
+ return true;
+ }
+
+ //-----------------------------------------------------------------------------------------
+ // Combines two path parts. wzPathLeft must be a directory path and may be either absolute
+ // or relative. wzPathRight may be a directory or file path and must be relative. The
+ // result is placed in wzBuffer and the number of chars written is placed in pcchBuffer on
+ // success; otherwise an error HRESULT is returned.
+ static HRESULT
+ Combine(LPCWSTR wzPathLeft, LPCWSTR wzPathRight, __in DWORD *pcchBuffer, __out_ecount(*pcchBuffer) LPWSTR wzBuffer)
+ {
+ STATIC_CONTRACT_NOTHROW;
+
+ HRESULT hr = S_OK;
+
+ if (clr::str::IsNullOrEmpty(wzPathLeft) || clr::str::IsNullOrEmpty(wzPathRight) || pcchBuffer == nullptr)
+ return E_INVALIDARG;
+
+ LPWSTR wzBuf = wzBuffer;
+ size_t cchBuf = *pcchBuffer;
+
+ IfFailRet(StringCchCopyExW(wzBuf, cchBuf, wzPathLeft, &wzBuf, &cchBuf, STRSAFE_NULL_ON_FAILURE));
+ IfFailRet(StringCchCatExW(wzBuf, cchBuf, wzBuf[-1] == DIRECTORY_SEPARATOR_CHAR_W ? W("") : DIRECTORY_SEPARATOR_STR_W, &wzBuf, &cchBuf, STRSAFE_NULL_ON_FAILURE));
+ IfFailRet(StringCchCatExW(wzBuf, cchBuf, wzPathRight, &wzBuf, &cchBuf, STRSAFE_NULL_ON_FAILURE));
+
+ return S_OK;
+ }
+
+ //-----------------------------------------------------------------------------------------
+ // Checks if the path provided is valid within the specified constraints.
+ // ***NOTE: does not yet check for invalid path characters.
+ static bool
+ IsValid(LPCWSTR wzPath, DWORD cchPath, bool fAllowLongFormat)
+ {
+ if (clr::str::IsNullOrEmpty(wzPath))
+ return false;
+
+ bool fIsLongFormat = HasLongFormatPrefix(wzPath);
+
+ if (fIsLongFormat && !fAllowLongFormat)
+ return false;
+
+ if (!fIsLongFormat && cchPath > _MAX_PATH)
+ return false;
+
+ return true;
+ }
+ };
+ }
+}
+
+#endif // _clr_fs_Path_h_
diff --git a/lib/coreclr/src/inc/clr/stack.h b/lib/coreclr/src/inc/clr/stack.h
new file mode 100644
index 0000000000..f9741b274f
--- /dev/null
+++ b/lib/coreclr/src/inc/clr/stack.h
@@ -0,0 +1,99 @@
+// 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 header provides a basic stack implementation
+
+#ifndef _clr_Stack_h_
+#define _clr_Stack_h_
+
+namespace clr
+{
+ //-------------------------------------------------------------------------------------------------
+ // A basic stack class.
+ //
+ template < typename T >
+ class Stack
+ {
+ private:
+ //---------------------------------------------------------------------------------------------
+ struct Link
+ {
+ template < typename A1 >
+ Link(A1 && a1, Link * next = nullptr)
+ : _value(std::forward(a1))
+ , _next(next)
+ {}
+
+ T _value;
+ Link * _next;
+ };
+
+ public:
+ //---------------------------------------------------------------------------------------------
+ // Empty stack constructor.
+ Stack()
+ : _top(nullptr)
+ , _size(0)
+ {}
+
+ //---------------------------------------------------------------------------------------------
+ // Move constructor.
+ Stack(Stack && stack)
+ : _top(nullptr)
+ , _size(0)
+ { *this = std::move(stack); }
+
+ //---------------------------------------------------------------------------------------------
+ ~Stack()
+ {
+ while (!empty())
+ {
+ pop();
+ }
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Move assignment.
+ Stack& operator=(Stack && stack)
+ { std::swap(_top, stack._top); std::swap(_size, stack._size); }
+
+ //---------------------------------------------------------------------------------------------
+ bool empty() const
+ { return _top == nullptr; }
+
+ //---------------------------------------------------------------------------------------------
+ size_t size() const
+ { return _size; }
+
+ //---------------------------------------------------------------------------------------------
+ T & top()
+ { return _top->_value; }
+
+ //---------------------------------------------------------------------------------------------
+ T const & top() const
+ { return _top->_value; }
+
+ //---------------------------------------------------------------------------------------------
+ template < typename A1 > inline
+ void push(A1 && value)
+ {
+ STATIC_CONTRACT_THROWS;
+ _top = new Link(std::forward(value), _top);
+ ++_size;
+ }
+
+ //---------------------------------------------------------------------------------------------
+ void pop()
+ { Link * del = _top; _top = _top->_next; --_size; delete del; }
+
+ private:
+ //---------------------------------------------------------------------------------------------
+ Link * _top;
+ size_t _size;
+ };
+} // namespace clr
+
+#endif // _clr_Stack_h_
diff --git a/lib/coreclr/src/inc/clr/str.h b/lib/coreclr/src/inc/clr/str.h
new file mode 100644
index 0000000000..94c8ed46b5
--- /dev/null
+++ b/lib/coreclr/src/inc/clr/str.h
@@ -0,0 +1,28 @@
+// 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 header provides general standard string services.
+//
+
+#ifndef _clr_str_h_
+#define _clr_str_h_
+
+namespace clr
+{
+ namespace str
+ {
+ //-----------------------------------------------------------------------------------------
+ // Returns true if the provided string is a null pointer or the empty string.
+ static inline bool
+ IsNullOrEmpty(LPCWSTR wzStr)
+ {
+ return wzStr == nullptr || *wzStr == W('\0');
+ }
+ }
+}
+
+#endif // _clr_str_h_
+
diff --git a/lib/coreclr/src/inc/clr/win32.h b/lib/coreclr/src/inc/clr/win32.h
new file mode 100644
index 0000000000..a0e00c6321
--- /dev/null
+++ b/lib/coreclr/src/inc/clr/win32.h
@@ -0,0 +1,38 @@
+// 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.
+//
+// clr/win32.h
+//
+// Provides Win32-specific utility functionality.
+//
+
+//
+
+#ifndef clr_win32_h
+#define clr_win32_h
+
+#include "winwrap.h"
+
+namespace clr
+{
+ namespace win32
+ {
+ // Prevents an HMODULE from being unloaded until process termination.
+ inline
+ HRESULT PreventModuleUnload(HMODULE hMod)
+ {
+ if (!WszGetModuleHandleEx(
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
+ reinterpret_cast(hMod),
+ &hMod))
+ {
+ return HRESULT_FROM_GetLastError();
+ }
+
+ return S_OK;
+ }
+ } // namespace win
+} // namespace clr
+
+#endif // clr_win32_h
diff --git a/lib/coreclr/src/inc/clr_std/algorithm b/lib/coreclr/src/inc/clr_std/algorithm
new file mode 100644
index 0000000000..92b4e8ece6
--- /dev/null
+++ b/lib/coreclr/src/inc/clr_std/algorithm
@@ -0,0 +1,119 @@
+// 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.
+
+//
+// clr_std/algorithm
+//
+// Copy of some key Standard Template Library functionality
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#ifdef USE_STL
+#include
+#else
+#ifndef __clr_std_algorithm_h__
+#define __clr_std_algorithm_h__
+
+namespace std
+{
+ template
+ iter find_if ( iter first, iter last, CompareFunc comp )
+ {
+ for ( ; first!=last ; first++ )
+ if ( comp(*first) )
+ break;
+ return first;
+ }
+
+ template
+ iter find(iter first, iter last, const T& val)
+ {
+ for (;first != last; first++)
+ {
+ if (*first == val)
+ break;
+ }
+ return first;
+ }
+
+ template
+ iter qsort_partition( iter first, iter last, iter pivot, comp compare )
+ {
+ iter lastMinusOne = last - 1;
+ swap(pivot, lastMinusOne);
+
+ // Pivot is at end
+ pivot = last - 1;
+
+ iter partitionLoc = first;
+
+ for (iter partitionWalk = first; partitionWalk != pivot; ++partitionWalk)
+ {
+ if (compare(*partitionWalk, *pivot))
+ {
+ swap(*partitionWalk, *partitionLoc);
+ partitionLoc++;
+ }
+ }
+ swap(*pivot, *partitionLoc);
+
+ return partitionLoc;
+ }
+
+ template
+ void sort_worker ( iter first, iter last, comp compare )
+ {
+ typename iter::difference_type RangeSize = last - first;
+
+ // When down to a list of size 1, be done
+ if (RangeSize < 2)
+ return;
+
+ // Pick pivot
+
+ // Use simple pick middle algorithm
+ iter pivotLoc = first + (RangeSize / 2);
+
+ // Partition
+ pivotLoc = qsort_partition(first, last, pivotLoc, compare);
+
+ // Sort first array
+ sort_worker(first, pivotLoc, compare);
+
+ // Sort second array
+ sort_worker(pivotLoc + 1, last, compare);
+ }
+
+ template
+ void sort ( iter first, iter last, comp compare )
+ {
+ sort_worker(first, last, compare);
+ if (first != last)
+ {
+ for (iter i = first; i < (last - 1); i++)
+ {
+ // Assert that the sort function works.
+ assert(!compare(*(i+1), *i));
+ }
+ }
+ }
+
+ template
+ OutIter transform( InIter first, InIter last, OutIter dest, Fn1 func )
+ {
+ for ( ; first!=last ; ++first, ++dest )
+ *dest = func(*first);
+ return dest;
+ }
+
+} // namespace std
+
+#endif /* __clr_std_algorithm_h__ */
+
+#endif // !USE_STL
+
+// Help the VIM editor figure out what kind of file this no-extension file is.
+// vim: filetype=cpp
diff --git a/lib/coreclr/src/inc/clr_std/string b/lib/coreclr/src/inc/clr_std/string
new file mode 100644
index 0000000000..66f219c8a8
--- /dev/null
+++ b/lib/coreclr/src/inc/clr_std/string
@@ -0,0 +1,426 @@
+// 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.
+
+//
+// clr_std/string
+//
+// Copy of some key Standard Template Library functionality
+//
+// This was created for use with SuperPMI. It has the minimal functionality needed by SuperPMI. It hasn't
+// been tested elsewhere.
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#ifdef USE_STL
+#include
+#else
+#ifndef __clr_std_string_h__
+#define __clr_std_string_h__
+
+#include "clr_std/vector"
+
+namespace std
+{
+
+template
+class basic_string
+{
+public:
+ typedef T value_type;
+ typedef size_t size_type;
+ typedef typename vector::iterator iterator;
+ typedef typename vector::const_iterator const_iterator;
+
+ basic_string()
+ : m_string(1) // start with a string of length 1 for null terminator
+ {
+ m_string[0] = T();
+ }
+
+ basic_string(const basic_string& _Right)
+ {
+ assign(_Right);
+ }
+
+ // Initialize a string with _Count characters from the string pointed at by _Ptr.
+ // If you want to include the trailing null character, _Count needs to include that.
+ basic_string(const value_type* _Ptr, size_type _Count)
+ : m_string(_Count + 1) // add 1 for a null terminator
+ {
+ copy(_Ptr, _Count);
+ }
+
+ basic_string(const value_type* _Ptr) : basic_string(_Ptr, c_len(_Ptr))
+ {
+ }
+
+ void reserve(size_t newcapacity)
+ {
+ m_string.reserve(newcapacity + 1); // add 1 for the null terminator
+ }
+
+ //
+ // Assignment
+ //
+
+ basic_string& operator=(const basic_string& _Right)
+ {
+ if (this != &_Right)
+ {
+ assign(_Right);
+ }
+ return (*this);
+ }
+
+ basic_string& assign(const basic_string& _Right)
+ {
+ m_string.resize(_Right.size() + 1); // +1 for null terminator
+ copy(_Right);
+ return (*this);
+ }
+
+ //
+ // Basic data copying
+ //
+
+ void copy(const basic_string& _Right)
+ {
+ assert(size() >= _Right.size());
+ size_type i;
+ for (i = 0; i < _Right.size(); i++)
+ {
+ m_string[i] = _Right.m_string[i];
+ }
+ m_string[i] = T();
+ }
+
+ void copy(const value_type* _Ptr, size_type _Count)
+ {
+ assert(size() >= _Count);
+ size_type i;
+ for (i = 0; i < _Count; i++)
+ {
+ m_string[i] = _Ptr[i];
+ }
+ m_string[i] = T();
+ }
+
+ //
+ // Appending
+ //
+
+ // Append a C-style string to the string.
+ basic_string& operator+=(const value_type* _Ptr)
+ {
+ size_type oldsize = size(); // doesn't include null terminator
+ size_type addsize = c_len(_Ptr); // doesn't include null terminator
+ size_type newsize = oldsize + addsize + 1;
+ m_string.resize(newsize);
+ size_type i;
+ for (i = oldsize; i < newsize - 1; i++)
+ {
+ m_string[i] = *_Ptr++;
+ }
+ m_string[i] = T();
+ return (*this);
+ }
+
+ basic_string& operator+=(const basic_string& _Right)
+ {
+ size_type oldsize = size(); // doesn't include null terminator
+ size_type addsize = _Right.size(); // doesn't include null terminator
+ size_type newsize = oldsize + addsize + 1;
+ m_string.resize(newsize);
+ size_type new_index = oldsize, right_index = 0;
+ while (right_index < addsize)
+ {
+ m_string[new_index] = _Right.m_string[right_index];
+ ++new_index;
+ ++right_index;
+ }
+ m_string[new_index] = T();
+ return (*this);
+ }
+
+ basic_string& operator+=(value_type _Ch)
+ {
+ size_type oldsize = size(); // doesn't include null terminator
+ m_string[oldsize] = _Ch; // Replace the null terminator with the new symbol.
+ m_string.push_back(T()); // Return the replaced terminator again.
+ return (*this);
+ }
+
+ ~basic_string()
+ {
+ // vector destructor does all the work
+ }
+
+ size_t size() const
+ {
+ assert(m_string.size() > 0);
+ return m_string.size() - 1; // Don't report the null terminator.
+ }
+
+ size_t length() const
+ {
+ return size();
+ }
+
+ T& operator[](size_t iIndex)
+ {
+ assert(iIndex < size() + 1); // allow looking at the null terminator
+ return m_string[iIndex];
+ }
+
+ const T* c_str() const
+ {
+ return m_string.data();
+ }
+
+ iterator begin()
+ {
+ return m_string.begin();
+ }
+
+ iterator end()
+ {
+ return m_string.end();
+ }
+
+ const_iterator cbegin() const
+ {
+ return m_string.cbegin();
+ }
+
+ const_iterator cend() const
+ {
+ return m_string.cend();
+ }
+
+ basic_string substr(size_type _Off = 0, size_type _Count = npos) const
+ {
+ size_type cursize = size();
+ if (_Off >= cursize)
+ {
+ // result will be empty
+ return basic_string();
+ }
+ else
+ {
+ if ((_Count == npos) || // No count specified; take the whole string suffix
+ (_Off + _Count > cursize)) // Count specified is too many characters; just take the whole suffix
+ {
+ _Count = cursize - _Off;
+ }
+ return basic_string(m_string.data() + _Off, _Count);
+ }
+ }
+
+ size_type find_last_of(value_type _Ch) const
+ {
+ for (size_type _Off = size(); _Off != 0; _Off--)
+ {
+ if (m_string[_Off - 1] == _Ch)
+ {
+ return _Off - 1;
+ }
+ }
+ return npos;
+ }
+
+ bool empty() const
+ {
+ return size() == 0;
+ }
+
+ int compare(const basic_string& _Str) const
+ {
+ size_type i;
+ size_type compareSize = size();
+ if (_Str.size() < compareSize)
+ {
+ // This string is longer; compare character-by-character only as many characters as we have.
+ compareSize = _Str.size();
+ }
+ for (i = 0; i < compareSize; i++)
+ {
+ if (m_string[i] != _Str.m_string[i])
+ {
+ if (m_string[i] < _Str.m_string[i])
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ }
+
+ // All the characters we compared were identical, but one string might be longer than the other.
+ if (size() == _Str.size())
+ {
+ // We compared everything.
+ return 0;
+ }
+ else if (size() < _Str.size())
+ {
+ // _Str has more characters than this.
+ return -1;
+ }
+ else
+ {
+ // this has more characters than _Str
+ return 1;
+ }
+ }
+
+ static const size_type npos = size_type(-1);
+
+private:
+
+ // Compute the length in characters of a null-terminated C-style string, not including the trailing null character.
+ // _Ptr must not be nullptr.
+ size_type c_len(const value_type* _Ptr)
+ {
+ size_type count;
+ for (count = 0; *_Ptr != T(); _Ptr++)
+ {
+ count++;
+ }
+ return count;
+ }
+
+ vector m_string; // use a vector<> to represent the string, to avoid reimplementing similar functionality
+
+}; // class basic_string
+
+//
+// String class instantiations
+//
+
+typedef basic_string string;
+
+//
+// Numeric conversions
+//
+
+// convert integer T to string
+template inline
+string _IntToString(const char *_Fmt, T _Val)
+{
+ const size_t MaxIntBufSize = 21; /* can hold -2^63 and 2^64 - 1, plus NUL */
+ char buf[MaxIntBufSize];
+ int len = sprintf_s(buf, MaxIntBufSize, _Fmt, _Val);
+ return (string(buf, len));
+}
+
+inline string to_string(int _Val)
+{
+ return (_IntToString("%d", _Val));
+}
+
+inline string to_string(unsigned int _Val)
+{
+ return (_IntToString("%u", _Val));
+}
+
+inline string to_string(long _Val)
+{
+ return (_IntToString("%ld", _Val));
+}
+
+inline string to_string(unsigned long _Val)
+{
+ return (_IntToString("%lu", _Val));
+}
+
+inline string to_string(long long _Val)
+{
+ return (_IntToString("%lld", _Val));
+}
+
+inline string to_string(unsigned long long _Val)
+{
+ return (_IntToString("%llu", _Val));
+}
+
+//
+// Comparisons
+//
+
+template inline
+bool operator==(
+ const basic_string& _Left,
+ const basic_string& _Right)
+{
+ return (_Left.compare(_Right) == 0);
+}
+
+template inline
+bool operator!=(
+ const basic_string& _Left,
+ const basic_string& _Right)
+{
+ return (!(_Left == _Right));
+}
+
+template inline
+bool operator<(
+ const basic_string& _Left,
+ const basic_string& _Right)
+{
+ return (_Left.compare(_Right) < 0);
+}
+
+template inline
+bool operator>(
+ const basic_string& _Left,
+ const basic_string& _Right)
+{
+ return (_Right < _Left);
+}
+
+template inline
+bool operator<=(
+ const basic_string& _Left,
+ const basic_string& _Right)
+{
+ return (!(_Right < _Left));
+}
+
+template inline
+bool operator>=(
+ const basic_string& _Left,
+ const basic_string& _Right)
+{
+ return (!(_Left < _Right));
+}
+
+//
+// String concatenation and other string operations
+//
+
+template inline
+basic_string operator+(
+ const basic_string& _Left,
+ const basic_string& _Right)
+{
+ basic_string ret;
+ ret.reserve(_Left.size() + _Right.size());
+ ret += _Left;
+ ret += _Right;
+ return ret;
+}
+
+}; // namespace std
+
+#endif /* __clr_std_string_h__ */
+
+#endif // !USE_STL
+
+// Help the VIM editor figure out what kind of file this no-extension file is.
+// vim: filetype=cpp
diff --git a/lib/coreclr/src/inc/clr_std/type_traits b/lib/coreclr/src/inc/clr_std/type_traits
new file mode 100644
index 0000000000..090694e320
--- /dev/null
+++ b/lib/coreclr/src/inc/clr_std/type_traits
@@ -0,0 +1,549 @@
+// 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.
+
+//
+// clr_std/utility
+//
+// Copy of some key Standard Template Library functionality.
+// See http://msdn.microsoft.com/en-us/library/bb982077.aspx for documentation.
+//
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#ifndef __clr_std_type_traits_h__
+#define __clr_std_type_traits_h__
+
+#ifdef USE_STL
+
+#include
+
+#else
+
+namespace std
+{
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS remove_const
+ template
+ struct remove_const
+ { // remove top level const qualifier
+ typedef _Ty type;
+ };
+
+ template
+ struct remove_const
+ { // remove top level const qualifier
+ typedef _Ty type;
+ };
+
+ template
+ struct remove_const
+ { // remove top level const qualifier
+ typedef _Ty type[];
+ };
+
+ template
+ struct remove_const
+ { // remove top level const qualifier
+ typedef _Ty type[_Nx];
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS remove_volatile
+ template
+ struct remove_volatile
+ { // remove top level volatile qualifier
+ typedef _Ty type;
+ };
+
+ template
+ struct remove_volatile
+ { // remove top level volatile qualifier
+ typedef _Ty type;
+ };
+
+ template
+ struct remove_volatile
+ { // remove top level volatile qualifier
+ typedef _Ty type[];
+ };
+
+ template
+ struct remove_volatile
+ { // remove top level volatile qualifier
+ typedef _Ty type[_Nx];
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS remove_cv
+ template
+ struct remove_cv
+ { // remove top level const and volatile qualifiers
+ typedef typename remove_const::type>::type type;
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE remove_reference
+ template
+ struct remove_reference
+ { // remove reference
+ typedef T type;
+ };
+
+ template
+ struct remove_reference
+ { // remove reference
+ typedef T type;
+ };
+
+ template
+ struct remove_reference
+ { // remove rvalue reference
+ typedef T type;
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE remove_pointer
+ template
+ struct remove_pointer
+ { // remove pointer
+ typedef T type;
+ };
+
+ template
+ struct remove_pointer
+ { // remove pointer
+ typedef T type;
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE FUNCTION identity
+ template
+ struct identity
+ { // map T to type unchanged
+ typedef T type;
+
+ inline
+ const T& operator()(const T& left) const
+ { // apply identity operator to operand
+ return (left);
+ }
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS integral_constant
+ template
+ struct integral_constant
+ { // convenient template for integral constant types
+ static const _Ty value = _Val;
+
+ typedef _Ty value_type;
+ typedef integral_constant<_Ty, _Val> type;
+ };
+
+ typedef integral_constant true_type;
+ typedef integral_constant false_type;
+
+ // TEMPLATE CLASS _Cat_base
+ template
+ struct _Cat_base
+ : false_type
+ { // base class for type predicates
+ };
+
+ template<>
+ struct _Cat_base
+ : true_type
+ { // base class for type predicates
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS enable_if
+ template
+ struct enable_if
+ { // type is undefined for assumed !_Test
+ };
+
+ template
+ struct enable_if
+ { // type is _Type for _Test
+ typedef _Type type;
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS conditional
+ template
+ struct conditional
+ { // type is _Ty2 for assumed !_Test
+ typedef _Ty2 type;
+ };
+
+ template
+ struct conditional
+ { // type is _Ty1 for _Test
+ typedef _Ty1 type;
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS is_lvalue_reference
+ template
+ struct is_lvalue_reference
+ : false_type
+ { // determine whether _Ty is an lvalue reference
+ };
+
+ template
+ struct is_lvalue_reference<_Ty&>
+ : true_type
+ { // determine whether _Ty is an lvalue reference
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS is_rvalue_reference
+ template
+ struct is_rvalue_reference
+ : false_type
+ { // determine whether _Ty is an rvalue reference
+ };
+
+ template
+ struct is_rvalue_reference<_Ty&&>
+ : true_type
+ { // determine whether _Ty is an rvalue reference
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS is_reference
+ template
+ struct is_reference
+ : conditional<
+ is_lvalue_reference<_Ty>::value || is_rvalue_reference<_Ty>::value,
+ true_type,
+ false_type>::type
+ { // determine whether _Ty is a reference
+ };
+
+ // TEMPLATE CLASS is_pointer
+ template
+ struct is_pointer
+ : false_type
+ { // determine whether _Ty is a pointer
+ };
+
+ template
+ struct is_pointer<_Ty *>
+ : true_type
+ { // determine whether _Ty is a pointer
+ };
+
+ // TEMPLATE CLASS _Is_integral
+ template
+ struct _Is_integral
+ : false_type
+ { // determine whether _Ty is integral
+ };
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ #ifdef _NATIVE_WCHAR_T_DEFINED
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+ #endif /* _NATIVE_WCHAR_T_DEFINED */
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+// On Unix 'long' is a 64-bit type (same as __int64) and the following two definitions
+// conflict with _Is_integral and _Is_integral.
+#ifndef PLATFORM_UNIX
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+#endif /* PLATFORM_UNIX */
+
+ #if _HAS_CHAR16_T_LANGUAGE_SUPPORT
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+ #endif /* _HAS_CHAR16_T_LANGUAGE_SUPPORT */
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ template<>
+ struct _Is_integral
+ : true_type
+ { // determine whether _Ty is integral
+ };
+
+ // TEMPLATE CLASS is_integral
+ template
+ struct is_integral
+ : _Is_integral::type>
+ { // determine whether _Ty is integral
+ };
+
+ // TEMPLATE CLASS _Is_floating_point
+ template
+ struct _Is_floating_point
+ : false_type
+ { // determine whether _Ty is floating point
+ };
+
+ template<>
+ struct _Is_floating_point
+ : true_type
+ { // determine whether _Ty is floating point
+ };
+
+ template<>
+ struct _Is_floating_point
+ : true_type
+ { // determine whether _Ty is floating point
+ };
+
+// In PAL, we define long as int and so this becomes int double,
+// which is a nonsense
+#ifndef FEATURE_PAL
+ template<>
+ struct _Is_floating_point
+ : true_type
+ { // determine whether _Ty is floating point
+ };
+#endif
+
+ // TEMPLATE CLASS is_floating_point
+ template
+ struct is_floating_point
+ : _Is_floating_point::type>
+ { // determine whether _Ty is floating point
+ };
+
+ // TEMPLATE CLASS is_arithmetic
+ template
+ struct is_arithmetic
+ : _Cat_base::value
+ || is_floating_point<_Ty>::value>
+ { // determine whether _Ty is an arithmetic type
+ };
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS is_signed
+ template
+ struct is_signed : conditional<
+ static_cast::type>(-1) < 0, true_type, false_type>::type {};
+
+ //-----------------------------------------------------------------------------------------
+ // TEMPLATE CLASS is_same
+ template
+ struct is_same : false_type { };
+
+ //-----------------------------------------------------------------------------------------
+ template
+ struct is_same