/mcs/tools/linker/Mono.Linker/LinkContext.cs

https://github.com/t-ashula/mono · C# · 258 lines · 187 code · 43 blank · 28 comment · 16 complexity · 6179d7de53035087513312cf5a326fc5 MD5 · raw file

  1. //
  2. // LinkContext.cs
  3. //
  4. // Author:
  5. // Jb Evain (jbevain@gmail.com)
  6. //
  7. // (C) 2006 Jb Evain
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using System.Collections;
  30. using System.IO;
  31. using Mono.Cecil;
  32. using Mono.Cecil.Cil;
  33. namespace Mono.Linker {
  34. public class LinkContext {
  35. Pipeline _pipeline;
  36. AssemblyAction _coreAction;
  37. Hashtable _actions;
  38. string _outputDirectory;
  39. Hashtable _parameters;
  40. bool _linkSymbols;
  41. AssemblyResolver _resolver;
  42. ReaderParameters _readerParameters;
  43. ISymbolReaderProvider _symbolReaderProvider;
  44. ISymbolWriterProvider _symbolWriterProvider;
  45. AnnotationStore _annotations;
  46. public Pipeline Pipeline {
  47. get { return _pipeline; }
  48. }
  49. public AnnotationStore Annotations {
  50. get { return _annotations; }
  51. }
  52. public string OutputDirectory {
  53. get { return _outputDirectory; }
  54. set { _outputDirectory = value; }
  55. }
  56. public AssemblyAction CoreAction {
  57. get { return _coreAction; }
  58. set { _coreAction = value; }
  59. }
  60. public bool LinkSymbols {
  61. get { return _linkSymbols; }
  62. set { _linkSymbols = value; }
  63. }
  64. public IDictionary Actions {
  65. get { return _actions; }
  66. }
  67. public AssemblyResolver Resolver {
  68. get { return _resolver; }
  69. }
  70. public ISymbolReaderProvider SymbolReaderProvider {
  71. get { return _symbolReaderProvider; }
  72. set { _symbolReaderProvider = value; }
  73. }
  74. public ISymbolWriterProvider SymbolWriterProvider {
  75. get { return _symbolWriterProvider; }
  76. set { _symbolWriterProvider = value; }
  77. }
  78. public LinkContext (Pipeline pipeline)
  79. : this (pipeline, new AssemblyResolver ())
  80. {
  81. }
  82. public LinkContext (Pipeline pipeline, AssemblyResolver resolver)
  83. {
  84. _pipeline = pipeline;
  85. _resolver = resolver;
  86. _actions = new Hashtable ();
  87. _parameters = new Hashtable ();
  88. _annotations = new AnnotationStore ();
  89. _readerParameters = new ReaderParameters {
  90. AssemblyResolver = _resolver,
  91. };
  92. }
  93. public TypeDefinition GetType (string fullName)
  94. {
  95. int pos = fullName.IndexOf (",");
  96. fullName = fullName.Replace ("+", "/");
  97. if (pos == -1) {
  98. foreach (AssemblyDefinition asm in GetAssemblies ()) {
  99. var type = asm.MainModule.GetType (fullName);
  100. if (type != null)
  101. return type;
  102. }
  103. return null;
  104. }
  105. string asmname = fullName.Substring (pos + 1);
  106. fullName = fullName.Substring (0, pos);
  107. AssemblyDefinition assembly = Resolve (AssemblyNameReference.Parse (asmname));
  108. return assembly.MainModule.GetType (fullName);
  109. }
  110. public AssemblyDefinition Resolve (string name)
  111. {
  112. if (File.Exists (name)) {
  113. AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly (name, _readerParameters);
  114. _resolver.CacheAssembly (assembly);
  115. return assembly;
  116. }
  117. return Resolve (new AssemblyNameReference (name, new Version ()));
  118. }
  119. public AssemblyDefinition Resolve (IMetadataScope scope)
  120. {
  121. AssemblyNameReference reference = GetReference (scope);
  122. try {
  123. AssemblyDefinition assembly = _resolver.Resolve (reference, _readerParameters);
  124. if (SeenFirstTime (assembly)) {
  125. SafeReadSymbols (assembly);
  126. SetAction (assembly);
  127. }
  128. return assembly;
  129. }
  130. catch {
  131. throw new AssemblyResolutionException (reference);
  132. }
  133. }
  134. bool SeenFirstTime (AssemblyDefinition assembly)
  135. {
  136. return !_annotations.HasAction (assembly);
  137. }
  138. public void SafeReadSymbols (AssemblyDefinition assembly)
  139. {
  140. if (!_linkSymbols)
  141. return;
  142. if (assembly.MainModule.HasSymbols)
  143. return;
  144. try {
  145. if (_symbolReaderProvider != null) {
  146. var symbolReader = _symbolReaderProvider.GetSymbolReader (
  147. assembly.MainModule,
  148. assembly.MainModule.FullyQualifiedName);
  149. _annotations.AddSymbolReader (assembly, symbolReader);
  150. assembly.MainModule.ReadSymbols (symbolReader);
  151. } else
  152. assembly.MainModule.ReadSymbols ();
  153. } catch {}
  154. }
  155. static AssemblyNameReference GetReference (IMetadataScope scope)
  156. {
  157. AssemblyNameReference reference;
  158. if (scope is ModuleDefinition) {
  159. AssemblyDefinition asm = ((ModuleDefinition) scope).Assembly;
  160. reference = asm.Name;
  161. } else
  162. reference = (AssemblyNameReference) scope;
  163. return reference;
  164. }
  165. void SetAction (AssemblyDefinition assembly)
  166. {
  167. AssemblyAction action = AssemblyAction.Link;
  168. AssemblyNameDefinition name = assembly.Name;
  169. if (_actions.Contains (name.Name))
  170. action = (AssemblyAction) _actions [name.Name];
  171. else if (IsCore (name))
  172. action = _coreAction;
  173. _annotations.SetAction (assembly, action);
  174. }
  175. static bool IsCore (AssemblyNameReference name)
  176. {
  177. switch (name.Name) {
  178. case "mscorlib":
  179. case "Accessibility":
  180. case "Mono.Security":
  181. // WPF
  182. case "PresentationFramework":
  183. case "PresentationCore":
  184. case "WindowsBase":
  185. case "UIAutomationProvider":
  186. case "UIAutomationTypes":
  187. case "PresentationUI":
  188. case "ReachFramework":
  189. return true;
  190. default:
  191. return name.Name.StartsWith ("System")
  192. || name.Name.StartsWith ("Microsoft");
  193. }
  194. }
  195. public AssemblyDefinition [] GetAssemblies ()
  196. {
  197. IDictionary cache = _resolver.AssemblyCache;
  198. AssemblyDefinition [] asms = new AssemblyDefinition [cache.Count];
  199. cache.Values.CopyTo (asms, 0);
  200. return asms;
  201. }
  202. public void SetParameter (string key, string value)
  203. {
  204. _parameters [key] = value;
  205. }
  206. public bool HasParameter (string key)
  207. {
  208. return _parameters.Contains (key);
  209. }
  210. public string GetParameter (string key)
  211. {
  212. return (string) _parameters [key];
  213. }
  214. }
  215. }