Merge pull request #4178 from ntherning/fix-broken-windows-build
[mono-project.git] / tools / offsets-tool / MonoAotOffsetsDumper.cs
blob0f9a984833d766fdc48ceba51617882d361f3237
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using System.Text.RegularExpressions;
6 using CppSharp.AST;
7 using CppSharp.AST.Extensions;
8 using CppSharp.Parser;
10 namespace CppSharp
12 /**
13 * This tool dumps the offsets of structures used in the Mono VM needed
14 * by the AOT compiler for cross-compiling code to target platforms
15 * different than the host the compiler is being invoked on.
17 * It takes two arguments: the path to your clone of the Mono repo and
18 * the path to the root of Android NDK.
20 static class MonoAotOffsetsDumper
22 static string MonoDir = @"";
24 static List<string> Abis = new List<string> ();
25 static string OutputDir;
27 static bool XamarinAndroid;
28 static string MonodroidDir = @"";
29 static string AndroidNdkPath = @"";
30 static string MaccoreDir = @"";
32 public enum TargetPlatform
34 Android,
35 iOS,
36 WatchOS,
39 public class Target
41 public Target()
43 Defines = new List<string>();
44 Arguments = new List<string>();
47 public Target(Target target)
49 Platform = target.Platform;
50 Triple = target.Triple;
51 Build = target.Build;
52 Defines = target.Defines;
53 Arguments = target.Arguments;
56 public TargetPlatform Platform;
57 public string Triple;
58 public string Build;
59 public List<string> Defines;
60 public List<string> Arguments;
63 public static List<Target> Targets = new List<Target>();
65 public static IEnumerable<Target> AndroidTargets
67 get { return Targets.Where ((t) => t.Platform == TargetPlatform.Android); }
70 public static IEnumerable<Target> DarwinTargets
72 get
74 return Targets.Where ((t) => t.Platform == TargetPlatform.iOS ||
75 t.Platform == TargetPlatform.WatchOS);
79 public static IEnumerable<Target> iOSTargets
81 get
83 return Targets.Where ((t) => t.Platform == TargetPlatform.iOS);
87 public static void SetupAndroidTargets()
89 Targets.Add (new Target {
90 Platform = TargetPlatform.Android,
91 Triple = "i686-none-linux-android",
92 Build = XamarinAndroid ? "x86" : "mono-x86",
93 Defines = { "TARGET_X86" }
94 });
96 Targets.Add (new Target {
97 Platform = TargetPlatform.Android,
98 Triple = "x86_64-none-linux-android",
99 Build = XamarinAndroid ? "x86_64" : "mono-x86_64",
100 Defines = { "TARGET_AMD64" }
101 });
103 Targets.Add (new Target {
104 Platform = TargetPlatform.Android,
105 Triple = "armv5-none-linux-androideabi",
106 Build = XamarinAndroid ? "armeabi" : "mono-armv6",
107 Defines = { "TARGET_ARM", "ARM_FPU_VFP", "HAVE_ARMV5" }
110 Targets.Add (new Target {
111 Platform = TargetPlatform.Android,
112 Triple = "armv7-none-linux-androideabi",
113 Build = XamarinAndroid ? "armeabi-v7a" : "mono-armv7",
114 Defines = { "TARGET_ARM", "ARM_FPU_VFP", "HAVE_ARMV5", "HAVE_ARMV6",
115 "HAVE_ARMV7"
119 Targets.Add (new Target {
120 Platform = TargetPlatform.Android,
121 Triple = "aarch64-v8a-linux-android",
122 Build = XamarinAndroid ? "arm64-v8a" : "mono-aarch64",
123 Defines = { "TARGET_ARM64" }
124 });
126 /*Targets.Add(new Target {
127 Platform = TargetPlatform.Android,
128 Triple = "mipsel-none-linux-android",
129 Build = "mono-mips",
130 Defines = { "TARGET_MIPS", "__mips__" }
131 });*/
133 foreach (var target in AndroidTargets)
134 target.Defines.AddRange (new string[] { "PLATFORM_ANDROID",
135 "TARGET_ANDROID", "MONO_CROSS_COMPILE", "USE_MONO_CTX"
139 public static void SetupiOSTargets()
141 Targets.Add(new Target {
142 Platform = TargetPlatform.iOS,
143 Triple = "arm-apple-darwin10",
144 Build = "target7",
145 Defines = { "TARGET_ARM", "ARM_FPU_VFP", "HAVE_ARMV5" }
148 Targets.Add(new Target {
149 Platform = TargetPlatform.iOS,
150 Triple = "aarch64-apple-darwin10",
151 Build = "target64",
152 Defines = { "TARGET_ARM64" }
155 foreach (var target in iOSTargets) {
156 target.Defines.AddRange (new string[] { "PLATFORM_DARWIN",
157 "TARGET_IOS", "TARGET_MACH", "MONO_CROSS_COMPILE", "USE_MONO_CTX",
158 "_XOPEN_SOURCE"
162 Targets.Add(new Target {
163 Platform = TargetPlatform.WatchOS,
164 Triple = "armv7k-apple-darwin",
165 Build = "targetwatch",
166 Defines = { "TARGET_ARM", "ARM_FPU_VFP", "HAVE_ARMV5" }
169 foreach (var target in DarwinTargets) {
170 target.Defines.AddRange (new string[] { "PLATFORM_DARWIN",
171 "TARGET_IOS", "TARGET_MACH", "MONO_CROSS_COMPILE", "USE_MONO_CTX",
172 "_XOPEN_SOURCE"
177 static bool GetParentSubDirectoryPath(string parent, out string subdir)
179 var directory = Directory.GetParent(Directory.GetCurrentDirectory());
181 while (directory != null) {
182 var path = Path.Combine(directory.FullName, parent);
184 if (Directory.Exists (path)) {
185 subdir = path;
186 return true;
189 directory = directory.Parent;
192 subdir = null;
193 return false;
196 public static void Main(string[] args)
198 ParseCommandLineArgs(args);
200 string monodroidDir;
201 if (!Directory.Exists (MonodroidDir) &&
202 GetParentSubDirectoryPath ("monodroid", out monodroidDir)) {
203 MonodroidDir = Path.Combine (monodroidDir);
206 if (Directory.Exists (MonodroidDir))
207 SetupAndroidTargets();
209 string maccoreDir;
210 if (!Directory.Exists (MaccoreDir) &&
211 GetParentSubDirectoryPath ("maccore", out maccoreDir)) {
212 MaccoreDir = Path.Combine (maccoreDir);
215 if (Directory.Exists(MaccoreDir))
216 SetupiOSTargets();
218 foreach (var target in Targets)
220 if (Abis.Any() && !Abis.Any (target.Triple.Contains))
221 continue;
223 Console.WriteLine();
224 Console.WriteLine("Processing triple: {0}", target.Triple);
226 var options = new DriverOptions();
228 var log = new TextDiagnosticPrinter();
229 var driver = new Driver(options, log);
231 Setup(driver, target);
232 driver.Setup();
234 BuildParseOptions(driver, target);
235 if (!driver.ParseCode())
236 return;
238 Dump(driver.Context.ASTContext, driver.Context.TargetInfo, target);
242 static void BuildParseOptions(Driver driver, Target target)
244 foreach (var header in driver.Options.Headers)
246 var source = driver.Project.AddFile(header);
247 source.Options = driver.BuildParserOptions(source);
249 if (header.Contains ("mini"))
250 continue;
252 source.Options.AddDefines ("HAVE_SGEN_GC");
253 source.Options.AddDefines ("HAVE_MOVING_COLLECTOR");
257 static string GetAndroidNdkPath()
259 if (!String.IsNullOrEmpty (AndroidNdkPath))
260 return AndroidNdkPath;
262 // Find the Android NDK's path from Monodroid's config.
263 var configFile = Path.Combine(MonodroidDir, "env.config");
264 if (!File.Exists(configFile))
265 throw new Exception("Expected a valid Monodroid environment config file at " + configFile);
267 var config = File.ReadAllText(configFile);
268 var match = Regex.Match(config, @"ANDROID_NDK_PATH\s*:=\s(.*)");
269 return match.Groups[1].Value.Trim();
272 static void ParseCommandLineArgs(string[] args)
274 var showHelp = false;
276 var options = new Mono.Options.OptionSet () {
277 { "abi=", "ABI triple to generate", v => Abis.Add(v) },
278 { "o|out=", "output directory", v => OutputDir = v },
279 { "maccore=", "include directory", v => MaccoreDir = v },
280 { "monodroid=", "top monodroid directory", v => MonodroidDir = v },
281 { "android-ndk=", "Path to Android NDK", v => AndroidNdkPath = v },
282 { "xamarin-android", "Generate for Xamarin.Android instead of monodroid", v => XamarinAndroid = true },
283 { "mono=", "include directory", v => MonoDir = v },
284 { "h|help", "show this message and exit", v => showHelp = v != null },
287 try {
288 options.Parse (args);
290 catch (Mono.Options.OptionException e) {
291 Console.WriteLine (e.Message);
292 Environment.Exit(0);
295 if (showHelp)
297 // Print usage and exit.
298 Console.WriteLine("{0} [--abi=triple] [--out=dir] "
299 + "[--monodroid/maccore=dir] [--mono=dir]",
300 AppDomain.CurrentDomain.FriendlyName);
301 Environment.Exit(0);
305 static void Setup(Driver driver, Target target)
307 var options = driver.Options;
308 options.DryRun = true;
309 options.LibraryName = "Mono";
311 var parserOptions = driver.ParserOptions;
312 parserOptions.Verbose = false;
313 parserOptions.MicrosoftMode = false;
314 parserOptions.AddArguments("-xc");
315 parserOptions.AddArguments("-std=gnu99");
316 parserOptions.AddDefines("CPPSHARP");
318 foreach (var define in target.Defines)
319 parserOptions.AddDefines(define);
321 SetupToolchainPaths(driver, target);
323 SetupMono(driver, target);
326 static void SetupMono(Driver driver, Target target)
328 string targetPath;
329 switch (target.Platform) {
330 case TargetPlatform.Android:
331 targetPath = Path.Combine (MonodroidDir, XamarinAndroid ? "build-tools/mono-runtimes/obj/Debug" : "builds");
332 break;
333 case TargetPlatform.WatchOS:
334 case TargetPlatform.iOS:
335 targetPath = Path.Combine (MaccoreDir, "builds");
336 break;
337 default:
338 throw new ArgumentOutOfRangeException ();
341 if (!Directory.Exists (MonoDir)) {
342 MonoDir = Path.GetFullPath (Path.Combine (targetPath, "../../mono"));
345 var targetBuild = Path.Combine(targetPath, target.Build);
347 if (!Directory.Exists(targetBuild))
348 throw new Exception(string.Format("Could not find the target build directory: {0}", targetBuild));
350 var includeDirs = new[]
352 targetBuild,
353 Path.Combine(targetBuild, "eglib", "src"),
354 MonoDir,
355 Path.Combine(MonoDir, "mono"),
356 Path.Combine(MonoDir, "mono", "mini"),
357 Path.Combine(MonoDir, "eglib", "src")
360 foreach (var inc in includeDirs)
361 driver.ParserOptions.AddIncludeDirs(inc);
363 var filesToParse = new[]
365 Path.Combine(MonoDir, "mono", "metadata", "metadata-cross-helpers.c"),
366 Path.Combine(MonoDir, "mono", "mini", "mini-cross-helpers.c"),
369 foreach (var file in filesToParse)
370 driver.Options.Headers.Add(file);
373 static void SetupMSVC(Driver driver, string triple)
375 var parserOptions = driver.ParserOptions;
377 parserOptions.Abi = Parser.AST.CppAbi.Microsoft;
378 parserOptions.MicrosoftMode = true;
380 var systemIncludeDirs = new[]
382 @"C:\Program Files (x86)\Windows Kits\8.1\Include\um",
383 @"C:\Program Files (x86)\Windows Kits\8.1\Include\shared"
386 foreach (var inc in systemIncludeDirs)
387 parserOptions.AddSystemIncludeDirs(inc);
389 parserOptions.AddDefines("HOST_WIN32");
392 static void SetupToolchainPaths(Driver driver, Target target)
394 switch (target.Platform) {
395 case TargetPlatform.Android:
396 SetupAndroidNDK(driver, target);
397 break;
398 case TargetPlatform.iOS:
399 case TargetPlatform.WatchOS:
400 SetupXcode(driver, target);
401 break;
402 default:
403 throw new ArgumentOutOfRangeException ();
407 static string GetArchFromTriple(string triple)
409 if (triple.Contains("mips"))
410 return "mips";
412 if (triple.Contains("arm64") || triple.Contains("aarch64"))
413 return "arm64";
415 if (triple.Contains("arm"))
416 return "arm";
418 if (triple.Contains("i686"))
419 return "x86";
421 if (triple.Contains("x86_64"))
422 return "x86_64";
424 throw new Exception("Unknown architecture from triple: " + triple);
427 static string GetXcodeToolchainPath()
429 var toolchains = Directory.EnumerateDirectories("/Applications", "Xcode*")
430 .ToList();
431 toolchains.Sort();
433 var toolchainPath = toolchains.LastOrDefault();
434 if (toolchainPath == null)
435 throw new Exception("Could not find a valid Xcode SDK");
437 return toolchainPath;
440 static string GetXcodeBuiltinIncludesFolder()
442 var toolchainPath = GetXcodeToolchainPath();
444 var toolchains = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
445 "Contents/Developer/Toolchains")).ToList();
446 toolchains.Sort();
448 toolchainPath = toolchains.LastOrDefault();
449 if (toolchainPath == null)
450 throw new Exception("Could not find a valid Xcode toolchain");
452 var includePaths = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
453 "usr/lib/clang")).ToList();
454 var includePath = includePaths.LastOrDefault();
456 if (includePath == null)
457 throw new Exception("Could not find a valid Clang include folder");
459 return Path.Combine(includePath, "include");
462 static string GetXcodeiOSIncludesFolder()
464 var toolchainPath = GetXcodeToolchainPath();
466 var sdkPaths = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
467 "Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs")).ToList();
468 var sdkPath = sdkPaths.LastOrDefault();
470 if (sdkPath == null)
471 throw new Exception("Could not find a valid iPhone SDK");
473 return Path.Combine(sdkPath, "usr/include");
476 static string GetXcodeWatchOSIncludesFolder()
478 var toolchainPath = GetXcodeToolchainPath();
480 var sdkPaths = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
481 "Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs")).ToList();
482 var sdkPath = sdkPaths.LastOrDefault();
484 if (sdkPath == null)
485 throw new Exception("Could not find a valid WatchOS SDK");
487 return Path.Combine(sdkPath, "usr/include");
490 static void SetupXcode(Driver driver, Target target)
492 var parserOptions = driver.ParserOptions;
494 var builtinsPath = GetXcodeBuiltinIncludesFolder();
495 string includePath;
497 switch (target.Platform) {
498 case TargetPlatform.iOS:
499 includePath = GetXcodeiOSIncludesFolder();
500 break;
501 case TargetPlatform.WatchOS:
502 includePath = GetXcodeWatchOSIncludesFolder();
503 break;
504 default:
505 throw new ArgumentOutOfRangeException ();
508 parserOptions.AddSystemIncludeDirs(builtinsPath);
509 parserOptions.AddSystemIncludeDirs(includePath);
511 parserOptions.NoBuiltinIncludes = true;
512 parserOptions.NoStandardIncludes = true;
513 parserOptions.TargetTriple = target.Triple;
516 static string GetAndroidHostToolchainPath()
518 var androidNdkPath = GetAndroidNdkPath ();
519 var toolchains = Directory.EnumerateDirectories(
520 Path.Combine(androidNdkPath, "toolchains"), "llvm*").ToList();
521 toolchains.Sort();
523 var toolchainPath = toolchains.LastOrDefault();
524 if (toolchainPath == null)
525 throw new Exception("Could not find a valid NDK host toolchain");
527 toolchains = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
528 "prebuilt")).ToList();
529 toolchains.Sort();
531 toolchainPath = toolchains.LastOrDefault();
532 if (toolchainPath == null)
533 throw new Exception("Could not find a valid NDK host toolchain");
535 return toolchainPath;
538 static string GetAndroidBuiltinIncludesFolder()
540 var toolchainPath = GetAndroidHostToolchainPath();
542 string clangToolchainPath = Path.Combine(toolchainPath, "lib64", "clang");
543 if (!Directory.Exists (clangToolchainPath))
544 clangToolchainPath = Path.Combine(toolchainPath, "lib", "clang");
546 string includePath = null;
547 if (Directory.Exists (clangToolchainPath)) {
548 var includePaths = Directory.EnumerateDirectories(clangToolchainPath).ToList();
549 includePath = includePaths.LastOrDefault();
551 if (includePath == null)
552 throw new Exception("Could not find a valid Clang include folder");
554 return Path.Combine(includePath, "include");
557 static void SetupAndroidNDK(Driver driver, Target target)
559 var options = driver.Options;
560 var parserOptions = driver.ParserOptions;
562 var builtinsPath = GetAndroidBuiltinIncludesFolder();
563 parserOptions.AddSystemIncludeDirs(builtinsPath);
565 var androidNdkRoot = GetAndroidNdkPath ();
566 const int androidNdkApiLevel = 21;
568 var toolchainPath = Path.Combine(androidNdkRoot, "platforms",
569 "android-" + androidNdkApiLevel, "arch-" + GetArchFromTriple(target.Triple),
570 "usr", "include");
571 parserOptions.AddSystemIncludeDirs(toolchainPath);
573 parserOptions.NoBuiltinIncludes = true;
574 parserOptions.NoStandardIncludes = true;
575 parserOptions.TargetTriple = target.Triple;
578 static uint GetTypeAlign(ParserTargetInfo target, ParserIntType type)
580 switch (type)
582 case ParserIntType.SignedChar:
583 case ParserIntType.UnsignedChar:
584 return target.CharAlign;
585 case ParserIntType.SignedShort:
586 case ParserIntType.UnsignedShort:
587 return target.ShortAlign;
588 case ParserIntType.SignedInt:
589 case ParserIntType.UnsignedInt:
590 return target.IntAlign;
591 case ParserIntType.SignedLong:
592 case ParserIntType.UnsignedLong:
593 return target.LongAlign;
594 case ParserIntType.SignedLongLong:
595 case ParserIntType.UnsignedLongLong:
596 return target.LongLongAlign;
597 default:
598 throw new Exception("Type has no alignment");
602 static uint GetTypeSize(ParserTargetInfo target, ParserIntType type)
604 switch (type)
606 case ParserIntType.SignedChar:
607 case ParserIntType.UnsignedChar:
608 return target.CharWidth;
609 case ParserIntType.SignedShort:
610 case ParserIntType.UnsignedShort:
611 return target.ShortWidth;
612 case ParserIntType.SignedInt:
613 case ParserIntType.UnsignedInt:
614 return target.IntWidth;
615 case ParserIntType.SignedLong:
616 case ParserIntType.UnsignedLong:
617 return target.LongWidth;
618 case ParserIntType.SignedLongLong:
619 case ParserIntType.UnsignedLongLong:
620 return target.LongLongWidth;
621 default:
622 throw new Exception("Type has no size");
626 static string GetTargetPlatformDefine(TargetPlatform target)
628 switch (target) {
629 case TargetPlatform.Android:
630 return "TARGET_ANDROID";
631 case TargetPlatform.iOS:
632 return "TARGET_IOS";
633 case TargetPlatform.WatchOS:
634 return "TARGET_WATCHOS";
635 default:
636 throw new ArgumentOutOfRangeException ();
640 static void Dump(ASTContext ctx, ParserTargetInfo targetInfo, Target target)
642 var targetFile = target.Triple;
644 if (!string.IsNullOrEmpty (OutputDir))
645 targetFile = Path.Combine (OutputDir, targetFile);
647 targetFile += ".h";
649 using (var writer = new StreamWriter(targetFile))
650 //using (var writer = Console.Out)
652 writer.WriteLine("#ifndef USED_CROSS_COMPILER_OFFSETS");
653 writer.WriteLine("#ifdef {0}", target.Defines[0]);
654 writer.WriteLine ("#ifdef {0}", GetTargetPlatformDefine (target.Platform));
655 writer.WriteLine("#ifndef HAVE_BOEHM_GC");
656 writer.WriteLine("#define HAS_CROSS_COMPILER_OFFSETS");
657 writer.WriteLine("#if defined (USE_CROSS_COMPILE_OFFSETS) || defined (MONO_CROSS_COMPILE)");
658 writer.WriteLine("#if !defined (DISABLE_METADATA_OFFSETS)");
659 writer.WriteLine("#define USED_CROSS_COMPILER_OFFSETS");
661 DumpAligns(writer, targetInfo);
662 DumpSizes(writer, targetInfo);
663 DumpMetadataOffsets(writer, ctx, target);
665 writer.WriteLine("#endif //disable metadata check");
667 DumpJITOffsets(writer, ctx);
669 writer.WriteLine("#endif //cross compiler checks");
670 writer.WriteLine("#endif //gc check");
671 writer.WriteLine("#endif //os check");
672 writer.WriteLine("#endif //arch check");
673 writer.WriteLine("#endif //USED_CROSS_COMPILER_OFFSETS check");
676 Console.WriteLine("Generated offsets file: {0}", targetFile);
679 static void DumpAligns(TextWriter writer, ParserTargetInfo target)
681 var aligns = new[]
683 new { Name = "gint8", Align = target.CharAlign},
684 new { Name = "gint16", Align = target.ShortAlign},
685 new { Name = "gint32", Align = target.IntAlign},
686 new { Name = "gint64", Align = GetTypeAlign(target, target.Int64Type)},
687 new { Name = "float", Align = target.FloatAlign},
688 new { Name = "double", Align = target.DoubleAlign},
689 new { Name = "gpointer", Align = GetTypeAlign(target, target.IntPtrType)},
692 // Write the alignment info for the basic types.
693 foreach (var align in aligns)
694 writer.WriteLine("DECL_ALIGN2({0},{1})", align.Name, align.Align / 8);
697 static void DumpSizes(TextWriter writer, ParserTargetInfo target)
699 var sizes = new[]
701 new { Name = "gint8", Size = target.CharWidth},
702 new { Name = "gint16", Size = target.ShortWidth},
703 new { Name = "gint32", Size = target.IntWidth},
704 new { Name = "gint64", Size = GetTypeSize(target, target.Int64Type)},
705 new { Name = "float", Size = target.FloatWidth},
706 new { Name = "double", Size = target.DoubleWidth},
707 new { Name = "gpointer", Size = GetTypeSize(target, target.IntPtrType)},
710 // Write the size info for the basic types.
711 foreach (var size in sizes)
712 writer.WriteLine("DECL_SIZE2({0},{1})", size.Name, size.Size / 8);
715 static Class GetClassFromTypedef(ITypedDecl typedef)
717 var type = typedef.Type.Desugar() as TagType;
718 if (type == null)
719 return null;
721 var @class = type.Declaration as Class;
723 return @class.IsIncomplete ?
724 (@class.CompleteDeclaration as Class) : @class;
727 static void DumpClasses(TextWriter writer, ASTContext ctx, IEnumerable<string> types,
728 bool optional = false)
730 foreach (var @struct in types)
732 var @class = ctx.FindCompleteClass(@struct);
733 if (@class == null)
734 @class = ctx.FindCompleteClass("_" + @struct);
736 if (@class == null)
738 var typedef = ctx.FindTypedef(@struct).FirstOrDefault(
739 decl => !decl.IsIncomplete);
741 if (typedef != null)
742 @class = GetClassFromTypedef(typedef);
745 if (@class == null && optional)
746 continue;
748 if (@class == null)
749 throw new Exception("Expected to find struct definition for " + @struct);
751 DumpStruct(writer, @class);
755 static void DumpMetadataOffsets(TextWriter writer, ASTContext ctx, Target target)
757 var types = new List<string>
759 "MonoObject",
760 "MonoObjectHandlePayload",
761 "MonoClass",
762 "MonoVTable",
763 "MonoDelegate",
764 "MonoInternalThread",
765 "MonoMulticastDelegate",
766 "MonoTransparentProxy",
767 "MonoRealProxy",
768 "MonoRemoteClass",
769 "MonoArray",
770 "MonoArrayBounds",
771 "MonoSafeHandle",
772 "MonoHandleRef",
773 "MonoComInteropProxy",
774 "MonoString",
775 "MonoException",
776 "MonoTypedRef",
777 "MonoThreadsSync",
778 "SgenThreadInfo",
779 "SgenClientThreadInfo"
782 DumpClasses(writer, ctx, types);
785 static void DumpJITOffsets(TextWriter writer, ASTContext ctx)
787 writer.WriteLine("#ifndef DISABLE_JIT_OFFSETS");
788 writer.WriteLine("#define USED_CROSS_COMPILER_OFFSETS");
790 var types = new[]
792 "MonoLMF",
793 "MonoMethodRuntimeGenericContext",
794 "MonoJitTlsData",
795 "MonoGSharedVtMethodRuntimeInfo",
796 "MonoContinuation",
797 "MonoContext",
798 "MonoDelegateTrampInfo",
801 DumpClasses(writer, ctx, types);
803 var optionalTypes = new[]
805 "GSharedVtCallInfo",
806 "SeqPointInfo",
807 "DynCallArgs",
808 "MonoLMFTramp",
811 DumpClasses(writer, ctx, optionalTypes, optional: true);
813 writer.WriteLine("#endif //disable jit check");
816 static void DumpStruct(TextWriter writer, Class @class)
818 var name = @class.Name;
819 if (name.StartsWith ("_", StringComparison.Ordinal))
820 name = name.Substring (1);
822 foreach (var field in @class.Fields)
824 if (field.IsBitField) continue;
826 if (name == "SgenThreadInfo" && field.Name == "regs")
827 continue;
829 var layout = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr);
831 writer.WriteLine("DECL_OFFSET2({0},{1},{2})", name, field.Name,
832 layout.Offset);