/Mono.Cecil/ModuleDefinition.cs

http://github.com/jbevain/cecil · C# · 1337 lines · 1049 code · 279 blank · 9 comment · 150 complexity · fd1c92cfcb2ac725182a20bcb51a1088 MD5 · raw file

  1. //
  2. // Author:
  3. // Jb Evain (jbevain@gmail.com)
  4. //
  5. // Copyright (c) 2008 - 2015 Jb Evain
  6. // Copyright (c) 2008 - 2011 Novell, Inc.
  7. //
  8. // Licensed under the MIT/X11 license.
  9. //
  10. using System;
  11. using System.Collections.Generic;
  12. using System.IO;
  13. using System.Threading;
  14. using SR = System.Reflection;
  15. using Mono.Cecil.Cil;
  16. using Mono.Cecil.Metadata;
  17. using Mono.Cecil.PE;
  18. using Mono.Collections.Generic;
  19. namespace Mono.Cecil {
  20. public enum ReadingMode {
  21. Immediate = 1,
  22. Deferred = 2,
  23. }
  24. public sealed class ReaderParameters {
  25. ReadingMode reading_mode;
  26. internal IAssemblyResolver assembly_resolver;
  27. internal IMetadataResolver metadata_resolver;
  28. internal IMetadataImporterProvider metadata_importer_provider;
  29. internal IReflectionImporterProvider reflection_importer_provider;
  30. Stream symbol_stream;
  31. ISymbolReaderProvider symbol_reader_provider;
  32. bool read_symbols;
  33. bool throw_symbols_mismatch;
  34. bool projections;
  35. bool in_memory;
  36. bool read_write;
  37. public ReadingMode ReadingMode {
  38. get { return reading_mode; }
  39. set { reading_mode = value; }
  40. }
  41. public bool InMemory {
  42. get { return in_memory; }
  43. set { in_memory = value; }
  44. }
  45. public IAssemblyResolver AssemblyResolver {
  46. get { return assembly_resolver; }
  47. set { assembly_resolver = value; }
  48. }
  49. public IMetadataResolver MetadataResolver {
  50. get { return metadata_resolver; }
  51. set { metadata_resolver = value; }
  52. }
  53. public IMetadataImporterProvider MetadataImporterProvider {
  54. get { return metadata_importer_provider; }
  55. set { metadata_importer_provider = value; }
  56. }
  57. public IReflectionImporterProvider ReflectionImporterProvider {
  58. get { return reflection_importer_provider; }
  59. set { reflection_importer_provider = value; }
  60. }
  61. public Stream SymbolStream {
  62. get { return symbol_stream; }
  63. set { symbol_stream = value; }
  64. }
  65. public ISymbolReaderProvider SymbolReaderProvider {
  66. get { return symbol_reader_provider; }
  67. set { symbol_reader_provider = value; }
  68. }
  69. public bool ReadSymbols {
  70. get { return read_symbols; }
  71. set { read_symbols = value; }
  72. }
  73. public bool ThrowIfSymbolsAreNotMatching {
  74. get { return throw_symbols_mismatch; }
  75. set { throw_symbols_mismatch = value; }
  76. }
  77. public bool ReadWrite {
  78. get { return read_write; }
  79. set { read_write = value; }
  80. }
  81. public bool ApplyWindowsRuntimeProjections {
  82. get { return projections; }
  83. set { projections = value; }
  84. }
  85. public ReaderParameters ()
  86. : this (ReadingMode.Deferred)
  87. {
  88. }
  89. public ReaderParameters (ReadingMode readingMode)
  90. {
  91. this.reading_mode = readingMode;
  92. this.throw_symbols_mismatch = true;
  93. }
  94. }
  95. public sealed class ModuleParameters {
  96. ModuleKind kind;
  97. TargetRuntime runtime;
  98. uint? timestamp;
  99. TargetArchitecture architecture;
  100. IAssemblyResolver assembly_resolver;
  101. IMetadataResolver metadata_resolver;
  102. IMetadataImporterProvider metadata_importer_provider;
  103. IReflectionImporterProvider reflection_importer_provider;
  104. public ModuleKind Kind {
  105. get { return kind; }
  106. set { kind = value; }
  107. }
  108. public TargetRuntime Runtime {
  109. get { return runtime; }
  110. set { runtime = value; }
  111. }
  112. public uint? Timestamp {
  113. get { return timestamp; }
  114. set { timestamp = value; }
  115. }
  116. public TargetArchitecture Architecture {
  117. get { return architecture; }
  118. set { architecture = value; }
  119. }
  120. public IAssemblyResolver AssemblyResolver {
  121. get { return assembly_resolver; }
  122. set { assembly_resolver = value; }
  123. }
  124. public IMetadataResolver MetadataResolver {
  125. get { return metadata_resolver; }
  126. set { metadata_resolver = value; }
  127. }
  128. public IMetadataImporterProvider MetadataImporterProvider {
  129. get { return metadata_importer_provider; }
  130. set { metadata_importer_provider = value; }
  131. }
  132. public IReflectionImporterProvider ReflectionImporterProvider {
  133. get { return reflection_importer_provider; }
  134. set { reflection_importer_provider = value; }
  135. }
  136. public ModuleParameters ()
  137. {
  138. this.kind = ModuleKind.Dll;
  139. this.Runtime = GetCurrentRuntime ();
  140. this.architecture = TargetArchitecture.I386;
  141. }
  142. static TargetRuntime GetCurrentRuntime ()
  143. {
  144. return typeof (object).Assembly.ImageRuntimeVersion.ParseRuntime ();
  145. }
  146. }
  147. public sealed class WriterParameters {
  148. uint? timestamp;
  149. Stream symbol_stream;
  150. ISymbolWriterProvider symbol_writer_provider;
  151. bool write_symbols;
  152. byte [] key_blob;
  153. string key_container;
  154. SR.StrongNameKeyPair key_pair;
  155. public uint? Timestamp {
  156. get { return timestamp; }
  157. set { timestamp = value; }
  158. }
  159. public Stream SymbolStream {
  160. get { return symbol_stream; }
  161. set { symbol_stream = value; }
  162. }
  163. public ISymbolWriterProvider SymbolWriterProvider {
  164. get { return symbol_writer_provider; }
  165. set { symbol_writer_provider = value; }
  166. }
  167. public bool WriteSymbols {
  168. get { return write_symbols; }
  169. set { write_symbols = value; }
  170. }
  171. public bool HasStrongNameKey {
  172. get { return key_pair != null || key_blob != null || key_container != null; }
  173. }
  174. public byte [] StrongNameKeyBlob {
  175. get { return key_blob; }
  176. set { key_blob = value; }
  177. }
  178. public string StrongNameKeyContainer {
  179. get { return key_container; }
  180. set { key_container = value; }
  181. }
  182. public SR.StrongNameKeyPair StrongNameKeyPair {
  183. get { return key_pair; }
  184. set { key_pair = value; }
  185. }
  186. public bool DeterministicMvid { get; set; }
  187. }
  188. public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider, ICustomDebugInformationProvider, IDisposable {
  189. internal Image Image;
  190. internal MetadataSystem MetadataSystem;
  191. internal ReadingMode ReadingMode;
  192. internal ISymbolReaderProvider SymbolReaderProvider;
  193. internal ISymbolReader symbol_reader;
  194. internal Disposable<IAssemblyResolver> assembly_resolver;
  195. internal IMetadataResolver metadata_resolver;
  196. internal TypeSystem type_system;
  197. internal readonly MetadataReader reader;
  198. readonly string file_name;
  199. internal string runtime_version;
  200. internal ModuleKind kind;
  201. WindowsRuntimeProjections projections;
  202. MetadataKind metadata_kind;
  203. TargetRuntime runtime;
  204. TargetArchitecture architecture;
  205. ModuleAttributes attributes;
  206. ModuleCharacteristics characteristics;
  207. Guid mvid;
  208. internal ushort linker_version = 8;
  209. internal ushort subsystem_major = 4;
  210. internal ushort subsystem_minor = 0;
  211. internal uint timestamp;
  212. internal AssemblyDefinition assembly;
  213. MethodDefinition entry_point;
  214. internal IReflectionImporter reflection_importer;
  215. internal IMetadataImporter metadata_importer;
  216. Collection<CustomAttribute> custom_attributes;
  217. Collection<AssemblyNameReference> references;
  218. Collection<ModuleReference> modules;
  219. Collection<Resource> resources;
  220. Collection<ExportedType> exported_types;
  221. TypeDefinitionCollection types;
  222. internal Collection<CustomDebugInformation> custom_infos;
  223. internal MetadataBuilder metadata_builder;
  224. public bool IsMain {
  225. get { return kind != ModuleKind.NetModule; }
  226. }
  227. public ModuleKind Kind {
  228. get { return kind; }
  229. set { kind = value; }
  230. }
  231. public MetadataKind MetadataKind {
  232. get { return metadata_kind; }
  233. set { metadata_kind = value; }
  234. }
  235. internal WindowsRuntimeProjections Projections {
  236. get {
  237. if (projections == null)
  238. Interlocked.CompareExchange (ref projections, new WindowsRuntimeProjections (this), null);
  239. return projections;
  240. }
  241. }
  242. public TargetRuntime Runtime {
  243. get { return runtime; }
  244. set {
  245. runtime = value;
  246. runtime_version = runtime.RuntimeVersionString ();
  247. }
  248. }
  249. public string RuntimeVersion {
  250. get { return runtime_version; }
  251. set {
  252. runtime_version = value;
  253. runtime = runtime_version.ParseRuntime ();
  254. }
  255. }
  256. public TargetArchitecture Architecture {
  257. get { return architecture; }
  258. set { architecture = value; }
  259. }
  260. public ModuleAttributes Attributes {
  261. get { return attributes; }
  262. set { attributes = value; }
  263. }
  264. public ModuleCharacteristics Characteristics {
  265. get { return characteristics; }
  266. set { characteristics = value; }
  267. }
  268. [Obsolete ("Use FileName")]
  269. public string FullyQualifiedName {
  270. get { return file_name; }
  271. }
  272. public string FileName {
  273. get { return file_name; }
  274. }
  275. public Guid Mvid {
  276. get { return mvid; }
  277. set { mvid = value; }
  278. }
  279. internal bool HasImage {
  280. get { return Image != null; }
  281. }
  282. public bool HasSymbols {
  283. get { return symbol_reader != null; }
  284. }
  285. public ISymbolReader SymbolReader {
  286. get { return symbol_reader; }
  287. }
  288. public override MetadataScopeType MetadataScopeType {
  289. get { return MetadataScopeType.ModuleDefinition; }
  290. }
  291. public AssemblyDefinition Assembly {
  292. get { return assembly; }
  293. }
  294. internal IReflectionImporter ReflectionImporter {
  295. get {
  296. if (reflection_importer == null)
  297. Interlocked.CompareExchange (ref reflection_importer, new DefaultReflectionImporter (this), null);
  298. return reflection_importer;
  299. }
  300. }
  301. internal IMetadataImporter MetadataImporter {
  302. get {
  303. if (metadata_importer == null)
  304. Interlocked.CompareExchange (ref metadata_importer, new DefaultMetadataImporter (this), null);
  305. return metadata_importer;
  306. }
  307. }
  308. public IAssemblyResolver AssemblyResolver {
  309. get {
  310. if (assembly_resolver.value == null) {
  311. lock (module_lock) {
  312. assembly_resolver = Disposable.Owned (new DefaultAssemblyResolver () as IAssemblyResolver);
  313. }
  314. }
  315. return assembly_resolver.value;
  316. }
  317. }
  318. public IMetadataResolver MetadataResolver {
  319. get {
  320. if (metadata_resolver == null)
  321. Interlocked.CompareExchange (ref metadata_resolver, new MetadataResolver (this.AssemblyResolver), null);
  322. return metadata_resolver;
  323. }
  324. }
  325. public TypeSystem TypeSystem {
  326. get {
  327. if (type_system == null)
  328. Interlocked.CompareExchange (ref type_system, TypeSystem.CreateTypeSystem (this), null);
  329. return type_system;
  330. }
  331. }
  332. public bool HasAssemblyReferences {
  333. get {
  334. if (references != null)
  335. return references.Count > 0;
  336. return HasImage && Image.HasTable (Table.AssemblyRef);
  337. }
  338. }
  339. public Collection<AssemblyNameReference> AssemblyReferences {
  340. get {
  341. if (references != null)
  342. return references;
  343. if (HasImage)
  344. return Read (ref references, this, (_, reader) => reader.ReadAssemblyReferences ());
  345. Interlocked.CompareExchange (ref references, new Collection<AssemblyNameReference> (), null);
  346. return references;
  347. }
  348. }
  349. public bool HasModuleReferences {
  350. get {
  351. if (modules != null)
  352. return modules.Count > 0;
  353. return HasImage && Image.HasTable (Table.ModuleRef);
  354. }
  355. }
  356. public Collection<ModuleReference> ModuleReferences {
  357. get {
  358. if (modules != null)
  359. return modules;
  360. if (HasImage)
  361. return Read (ref modules, this, (_, reader) => reader.ReadModuleReferences ());
  362. Interlocked.CompareExchange (ref modules, new Collection<ModuleReference> (), null);
  363. return modules;
  364. }
  365. }
  366. public bool HasResources {
  367. get {
  368. if (resources != null)
  369. return resources.Count > 0;
  370. if (HasImage)
  371. return Image.HasTable (Table.ManifestResource) || Read (this, (_, reader) => reader.HasFileResource ());
  372. return false;
  373. }
  374. }
  375. public Collection<Resource> Resources {
  376. get {
  377. if (resources != null)
  378. return resources;
  379. if (HasImage)
  380. return Read (ref resources, this, (_, reader) => reader.ReadResources ());
  381. Interlocked.CompareExchange (ref resources, new Collection<Resource> (), null);
  382. return resources;
  383. }
  384. }
  385. public bool HasCustomAttributes {
  386. get {
  387. if (custom_attributes != null)
  388. return custom_attributes.Count > 0;
  389. return this.GetHasCustomAttributes (this);
  390. }
  391. }
  392. public Collection<CustomAttribute> CustomAttributes {
  393. get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, this)); }
  394. }
  395. public bool HasTypes {
  396. get {
  397. if (types != null)
  398. return types.Count > 0;
  399. return HasImage && Image.HasTable (Table.TypeDef);
  400. }
  401. }
  402. public Collection<TypeDefinition> Types {
  403. get {
  404. if (types != null)
  405. return types;
  406. if (HasImage)
  407. return Read (ref types, this, (_, reader) => reader.ReadTypes ());
  408. Interlocked.CompareExchange (ref types, new TypeDefinitionCollection (this), null);
  409. return types;
  410. }
  411. }
  412. public bool HasExportedTypes {
  413. get {
  414. if (exported_types != null)
  415. return exported_types.Count > 0;
  416. return HasImage && Image.HasTable (Table.ExportedType);
  417. }
  418. }
  419. public Collection<ExportedType> ExportedTypes {
  420. get {
  421. if (exported_types != null)
  422. return exported_types;
  423. if (HasImage)
  424. return Read (ref exported_types, this, (_, reader) => reader.ReadExportedTypes ());
  425. Interlocked.CompareExchange (ref exported_types, new Collection<ExportedType> (), null);
  426. return exported_types;
  427. }
  428. }
  429. public MethodDefinition EntryPoint {
  430. get {
  431. if (entry_point != null)
  432. return entry_point;
  433. if (HasImage)
  434. return Read (ref entry_point, this, (_, reader) => reader.ReadEntryPoint ());
  435. return entry_point = null;
  436. }
  437. set { entry_point = value; }
  438. }
  439. public bool HasCustomDebugInformations {
  440. get {
  441. return custom_infos != null && custom_infos.Count > 0;
  442. }
  443. }
  444. public Collection<CustomDebugInformation> CustomDebugInformations {
  445. get {
  446. if (custom_infos == null)
  447. Interlocked.CompareExchange (ref custom_infos, new Collection<CustomDebugInformation> (), null);
  448. return custom_infos;
  449. }
  450. }
  451. internal ModuleDefinition ()
  452. {
  453. this.MetadataSystem = new MetadataSystem ();
  454. this.token = new MetadataToken (TokenType.Module, 1);
  455. }
  456. internal ModuleDefinition (Image image)
  457. : this ()
  458. {
  459. this.Image = image;
  460. this.kind = image.Kind;
  461. this.RuntimeVersion = image.RuntimeVersion;
  462. this.architecture = image.Architecture;
  463. this.attributes = image.Attributes;
  464. this.characteristics = image.Characteristics;
  465. this.linker_version = image.LinkerVersion;
  466. this.subsystem_major = image.SubSystemMajor;
  467. this.subsystem_minor = image.SubSystemMinor;
  468. this.file_name = image.FileName;
  469. this.timestamp = image.Timestamp;
  470. this.reader = new MetadataReader (this);
  471. }
  472. public void Dispose ()
  473. {
  474. if (Image != null)
  475. Image.Dispose ();
  476. if (symbol_reader != null)
  477. symbol_reader.Dispose ();
  478. if (assembly_resolver.value != null)
  479. assembly_resolver.Dispose ();
  480. }
  481. public bool HasTypeReference (string fullName)
  482. {
  483. return HasTypeReference (string.Empty, fullName);
  484. }
  485. public bool HasTypeReference (string scope, string fullName)
  486. {
  487. Mixin.CheckFullName (fullName);
  488. if (!HasImage)
  489. return false;
  490. return GetTypeReference (scope, fullName) != null;
  491. }
  492. public bool TryGetTypeReference (string fullName, out TypeReference type)
  493. {
  494. return TryGetTypeReference (string.Empty, fullName, out type);
  495. }
  496. public bool TryGetTypeReference (string scope, string fullName, out TypeReference type)
  497. {
  498. Mixin.CheckFullName (fullName);
  499. if (!HasImage) {
  500. type = null;
  501. return false;
  502. }
  503. return (type = GetTypeReference (scope, fullName)) != null;
  504. }
  505. TypeReference GetTypeReference (string scope, string fullname)
  506. {
  507. return Read (new Row<string, string> (scope, fullname), (row, reader) => reader.GetTypeReference (row.Col1, row.Col2));
  508. }
  509. public IEnumerable<TypeReference> GetTypeReferences ()
  510. {
  511. if (!HasImage)
  512. return Empty<TypeReference>.Array;
  513. return Read (this, (_, reader) => reader.GetTypeReferences ());
  514. }
  515. public IEnumerable<MemberReference> GetMemberReferences ()
  516. {
  517. if (!HasImage)
  518. return Empty<MemberReference>.Array;
  519. return Read (this, (_, reader) => reader.GetMemberReferences ());
  520. }
  521. public IEnumerable<CustomAttribute> GetCustomAttributes ()
  522. {
  523. if (!HasImage)
  524. return Empty<CustomAttribute>.Array;
  525. return Read (this, (_, reader) => reader.GetCustomAttributes ());
  526. }
  527. public TypeReference GetType (string fullName, bool runtimeName)
  528. {
  529. return runtimeName
  530. ? TypeParser.ParseType (this, fullName, typeDefinitionOnly: true)
  531. : GetType (fullName);
  532. }
  533. public TypeDefinition GetType (string fullName)
  534. {
  535. Mixin.CheckFullName (fullName);
  536. var position = fullName.IndexOf ('/');
  537. if (position > 0)
  538. return GetNestedType (fullName);
  539. return ((TypeDefinitionCollection) this.Types).GetType (fullName);
  540. }
  541. public TypeDefinition GetType (string @namespace, string name)
  542. {
  543. Mixin.CheckName (name);
  544. return ((TypeDefinitionCollection) this.Types).GetType (@namespace ?? string.Empty, name);
  545. }
  546. public IEnumerable<TypeDefinition> GetTypes ()
  547. {
  548. return GetTypes (Types);
  549. }
  550. static IEnumerable<TypeDefinition> GetTypes (Collection<TypeDefinition> types)
  551. {
  552. for (int i = 0; i < types.Count; i++) {
  553. var type = types [i];
  554. yield return type;
  555. if (!type.HasNestedTypes)
  556. continue;
  557. foreach (var nested in GetTypes (type.NestedTypes))
  558. yield return nested;
  559. }
  560. }
  561. TypeDefinition GetNestedType (string fullname)
  562. {
  563. var names = fullname.Split ('/');
  564. var type = GetType (names [0]);
  565. if (type == null)
  566. return null;
  567. for (int i = 1; i < names.Length; i++) {
  568. var nested_type = type.GetNestedType (names [i]);
  569. if (nested_type == null)
  570. return null;
  571. type = nested_type;
  572. }
  573. return type;
  574. }
  575. internal FieldDefinition Resolve (FieldReference field)
  576. {
  577. return MetadataResolver.Resolve (field);
  578. }
  579. internal MethodDefinition Resolve (MethodReference method)
  580. {
  581. return MetadataResolver.Resolve (method);
  582. }
  583. internal TypeDefinition Resolve (TypeReference type)
  584. {
  585. return MetadataResolver.Resolve (type);
  586. }
  587. static void CheckContext (IGenericParameterProvider context, ModuleDefinition module)
  588. {
  589. if (context == null)
  590. return;
  591. if (context.Module != module)
  592. throw new ArgumentException ();
  593. }
  594. [Obsolete ("Use ImportReference", error: false)]
  595. public TypeReference Import (Type type)
  596. {
  597. return ImportReference (type, null);
  598. }
  599. public TypeReference ImportReference (Type type)
  600. {
  601. return ImportReference (type, null);
  602. }
  603. [Obsolete ("Use ImportReference", error: false)]
  604. public TypeReference Import (Type type, IGenericParameterProvider context)
  605. {
  606. return ImportReference (type, context);
  607. }
  608. public TypeReference ImportReference (Type type, IGenericParameterProvider context)
  609. {
  610. Mixin.CheckType (type);
  611. CheckContext (context, this);
  612. return ReflectionImporter.ImportReference (type, context);
  613. }
  614. [Obsolete ("Use ImportReference", error: false)]
  615. public FieldReference Import (SR.FieldInfo field)
  616. {
  617. return ImportReference (field, null);
  618. }
  619. [Obsolete ("Use ImportReference", error: false)]
  620. public FieldReference Import (SR.FieldInfo field, IGenericParameterProvider context)
  621. {
  622. return ImportReference (field, context);
  623. }
  624. public FieldReference ImportReference (SR.FieldInfo field)
  625. {
  626. return ImportReference (field, null);
  627. }
  628. public FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context)
  629. {
  630. Mixin.CheckField (field);
  631. CheckContext (context, this);
  632. return ReflectionImporter.ImportReference (field, context);
  633. }
  634. [Obsolete ("Use ImportReference", error: false)]
  635. public MethodReference Import (SR.MethodBase method)
  636. {
  637. return ImportReference (method, null);
  638. }
  639. [Obsolete ("Use ImportReference", error: false)]
  640. public MethodReference Import (SR.MethodBase method, IGenericParameterProvider context)
  641. {
  642. return ImportReference (method, context);
  643. }
  644. public MethodReference ImportReference (SR.MethodBase method)
  645. {
  646. return ImportReference (method, null);
  647. }
  648. public MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context)
  649. {
  650. Mixin.CheckMethod (method);
  651. CheckContext (context, this);
  652. return ReflectionImporter.ImportReference (method, context);
  653. }
  654. [Obsolete ("Use ImportReference", error: false)]
  655. public TypeReference Import (TypeReference type)
  656. {
  657. return ImportReference (type, null);
  658. }
  659. [Obsolete ("Use ImportReference", error: false)]
  660. public TypeReference Import (TypeReference type, IGenericParameterProvider context)
  661. {
  662. return ImportReference (type, context);
  663. }
  664. public TypeReference ImportReference (TypeReference type)
  665. {
  666. return ImportReference (type, null);
  667. }
  668. public TypeReference ImportReference (TypeReference type, IGenericParameterProvider context)
  669. {
  670. Mixin.CheckType (type);
  671. if (type.Module == this)
  672. return type;
  673. CheckContext (context, this);
  674. return MetadataImporter.ImportReference (type, context);
  675. }
  676. [Obsolete ("Use ImportReference", error: false)]
  677. public FieldReference Import (FieldReference field)
  678. {
  679. return ImportReference (field, null);
  680. }
  681. [Obsolete ("Use ImportReference", error: false)]
  682. public FieldReference Import (FieldReference field, IGenericParameterProvider context)
  683. {
  684. return ImportReference (field, context);
  685. }
  686. public FieldReference ImportReference (FieldReference field)
  687. {
  688. return ImportReference (field, null);
  689. }
  690. public FieldReference ImportReference (FieldReference field, IGenericParameterProvider context)
  691. {
  692. Mixin.CheckField (field);
  693. if (field.Module == this)
  694. return field;
  695. CheckContext (context, this);
  696. return MetadataImporter.ImportReference (field, context);
  697. }
  698. [Obsolete ("Use ImportReference", error: false)]
  699. public MethodReference Import (MethodReference method)
  700. {
  701. return ImportReference (method, null);
  702. }
  703. [Obsolete ("Use ImportReference", error: false)]
  704. public MethodReference Import (MethodReference method, IGenericParameterProvider context)
  705. {
  706. return ImportReference (method, context);
  707. }
  708. public MethodReference ImportReference (MethodReference method)
  709. {
  710. return ImportReference (method, null);
  711. }
  712. public MethodReference ImportReference (MethodReference method, IGenericParameterProvider context)
  713. {
  714. Mixin.CheckMethod (method);
  715. if (method.Module == this)
  716. return method;
  717. CheckContext (context, this);
  718. return MetadataImporter.ImportReference (method, context);
  719. }
  720. public IMetadataTokenProvider LookupToken (int token)
  721. {
  722. return LookupToken (new MetadataToken ((uint) token));
  723. }
  724. public IMetadataTokenProvider LookupToken (MetadataToken token)
  725. {
  726. return Read (token, (t, reader) => reader.LookupToken (t));
  727. }
  728. readonly object module_lock = new object();
  729. internal object SyncRoot {
  730. get { return module_lock; }
  731. }
  732. internal void Read<TItem> (TItem item, Action<TItem, MetadataReader> read)
  733. {
  734. lock (module_lock) {
  735. var position = reader.position;
  736. var context = reader.context;
  737. read (item, reader);
  738. reader.position = position;
  739. reader.context = context;
  740. }
  741. }
  742. internal TRet Read<TItem, TRet> (TItem item, Func<TItem, MetadataReader, TRet> read)
  743. {
  744. lock (module_lock) {
  745. var position = reader.position;
  746. var context = reader.context;
  747. var ret = read (item, reader);
  748. reader.position = position;
  749. reader.context = context;
  750. return ret;
  751. }
  752. }
  753. internal TRet Read<TItem, TRet> (ref TRet variable, TItem item, Func<TItem, MetadataReader, TRet> read) where TRet : class
  754. {
  755. lock (module_lock) {
  756. if (variable != null)
  757. return variable;
  758. var position = reader.position;
  759. var context = reader.context;
  760. var ret = read (item, reader);
  761. reader.position = position;
  762. reader.context = context;
  763. return variable = ret;
  764. }
  765. }
  766. public bool HasDebugHeader {
  767. get { return Image != null && Image.DebugHeader != null; }
  768. }
  769. public ImageDebugHeader GetDebugHeader ()
  770. {
  771. return Image.DebugHeader ?? new ImageDebugHeader ();
  772. }
  773. public static ModuleDefinition CreateModule (string name, ModuleKind kind)
  774. {
  775. return CreateModule (name, new ModuleParameters { Kind = kind });
  776. }
  777. public static ModuleDefinition CreateModule (string name, ModuleParameters parameters)
  778. {
  779. Mixin.CheckName (name);
  780. Mixin.CheckParameters (parameters);
  781. var module = new ModuleDefinition {
  782. Name = name,
  783. kind = parameters.Kind,
  784. timestamp = parameters.Timestamp ?? Mixin.GetTimestamp (),
  785. Runtime = parameters.Runtime,
  786. architecture = parameters.Architecture,
  787. mvid = Guid.NewGuid (),
  788. Attributes = ModuleAttributes.ILOnly,
  789. Characteristics = (ModuleCharacteristics) 0x8540,
  790. };
  791. if (parameters.AssemblyResolver != null)
  792. module.assembly_resolver = Disposable.NotOwned (parameters.AssemblyResolver);
  793. if (parameters.MetadataResolver != null)
  794. module.metadata_resolver = parameters.MetadataResolver;
  795. if (parameters.MetadataImporterProvider != null)
  796. module.metadata_importer = parameters.MetadataImporterProvider.GetMetadataImporter (module);
  797. if (parameters.ReflectionImporterProvider != null)
  798. module.reflection_importer = parameters.ReflectionImporterProvider.GetReflectionImporter (module);
  799. if (parameters.Kind != ModuleKind.NetModule) {
  800. var assembly = new AssemblyDefinition ();
  801. module.assembly = assembly;
  802. module.assembly.Name = CreateAssemblyName (name);
  803. assembly.main_module = module;
  804. }
  805. module.Types.Add (new TypeDefinition (string.Empty, "<Module>", TypeAttributes.NotPublic));
  806. return module;
  807. }
  808. static AssemblyNameDefinition CreateAssemblyName (string name)
  809. {
  810. if (name.EndsWith (".dll") || name.EndsWith (".exe"))
  811. name = name.Substring (0, name.Length - 4);
  812. return new AssemblyNameDefinition (name, Mixin.ZeroVersion);
  813. }
  814. public void ReadSymbols ()
  815. {
  816. if (string.IsNullOrEmpty (file_name))
  817. throw new InvalidOperationException ();
  818. var provider = new DefaultSymbolReaderProvider (throwIfNoSymbol: true);
  819. ReadSymbols (provider.GetSymbolReader (this, file_name), throwIfSymbolsAreNotMaching: true);
  820. }
  821. public void ReadSymbols (ISymbolReader reader)
  822. {
  823. ReadSymbols(reader, throwIfSymbolsAreNotMaching: true);
  824. }
  825. public void ReadSymbols (ISymbolReader reader, bool throwIfSymbolsAreNotMaching)
  826. {
  827. if (reader == null)
  828. throw new ArgumentNullException ("reader");
  829. symbol_reader = reader;
  830. if (!symbol_reader.ProcessDebugHeader (GetDebugHeader ())) {
  831. symbol_reader = null;
  832. if (throwIfSymbolsAreNotMaching)
  833. throw new SymbolsNotMatchingException ("Symbols were found but are not matching the assembly");
  834. return;
  835. }
  836. if (HasImage && ReadingMode == ReadingMode.Immediate) {
  837. var immediate_reader = new ImmediateModuleReader (Image);
  838. immediate_reader.ReadSymbols (this);
  839. }
  840. }
  841. public static ModuleDefinition ReadModule (string fileName)
  842. {
  843. return ReadModule (fileName, new ReaderParameters (ReadingMode.Deferred));
  844. }
  845. public static ModuleDefinition ReadModule (string fileName, ReaderParameters parameters)
  846. {
  847. var stream = GetFileStream (fileName, FileMode.Open, parameters.ReadWrite ? FileAccess.ReadWrite : FileAccess.Read, FileShare.Read);
  848. if (parameters.InMemory) {
  849. var memory = new MemoryStream (stream.CanSeek ? (int) stream.Length : 0);
  850. using (stream)
  851. stream.CopyTo (memory);
  852. memory.Position = 0;
  853. stream = memory;
  854. }
  855. try {
  856. return ReadModule (Disposable.Owned (stream), fileName, parameters);
  857. } catch (Exception) {
  858. stream.Dispose ();
  859. throw;
  860. }
  861. }
  862. static Stream GetFileStream (string fileName, FileMode mode, FileAccess access, FileShare share)
  863. {
  864. Mixin.CheckFileName (fileName);
  865. return new FileStream (fileName, mode, access, share);
  866. }
  867. public static ModuleDefinition ReadModule (Stream stream)
  868. {
  869. return ReadModule (stream, new ReaderParameters (ReadingMode.Deferred));
  870. }
  871. public static ModuleDefinition ReadModule (Stream stream, ReaderParameters parameters)
  872. {
  873. Mixin.CheckStream (stream);
  874. Mixin.CheckReadSeek (stream);
  875. return ReadModule (Disposable.NotOwned (stream), stream.GetFileName (), parameters);
  876. }
  877. static ModuleDefinition ReadModule (Disposable<Stream> stream, string fileName, ReaderParameters parameters)
  878. {
  879. Mixin.CheckParameters (parameters);
  880. return ModuleReader.CreateModule (
  881. ImageReader.ReadImage (stream, fileName),
  882. parameters);
  883. }
  884. public void Write (string fileName)
  885. {
  886. Write (fileName, new WriterParameters ());
  887. }
  888. public void Write (string fileName, WriterParameters parameters)
  889. {
  890. Mixin.CheckParameters (parameters);
  891. var file = GetFileStream (fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
  892. ModuleWriter.WriteModule (this, Disposable.Owned (file), parameters);
  893. }
  894. public void Write ()
  895. {
  896. Write (new WriterParameters ());
  897. }
  898. public void Write (WriterParameters parameters)
  899. {
  900. if (!HasImage)
  901. throw new InvalidOperationException ();
  902. Write (Image.Stream.value, parameters);
  903. }
  904. public void Write (Stream stream)
  905. {
  906. Write (stream, new WriterParameters ());
  907. }
  908. public void Write (Stream stream, WriterParameters parameters)
  909. {
  910. Mixin.CheckStream (stream);
  911. Mixin.CheckWriteSeek (stream);
  912. Mixin.CheckParameters (parameters);
  913. ModuleWriter.WriteModule (this, Disposable.NotOwned (stream), parameters);
  914. }
  915. }
  916. static partial class Mixin {
  917. public enum Argument {
  918. name,
  919. fileName,
  920. fullName,
  921. stream,
  922. type,
  923. method,
  924. field,
  925. parameters,
  926. module,
  927. modifierType,
  928. eventType,
  929. fieldType,
  930. declaringType,
  931. returnType,
  932. propertyType,
  933. interfaceType,
  934. constraintType,
  935. }
  936. public static void CheckName (object name)
  937. {
  938. if (name == null)
  939. throw new ArgumentNullException (Argument.name.ToString ());
  940. }
  941. public static void CheckName (string name)
  942. {
  943. if (string.IsNullOrEmpty (name))
  944. throw new ArgumentNullOrEmptyException (Argument.name.ToString ());
  945. }
  946. public static void CheckFileName (string fileName)
  947. {
  948. if (string.IsNullOrEmpty (fileName))
  949. throw new ArgumentNullOrEmptyException (Argument.fileName.ToString ());
  950. }
  951. public static void CheckFullName (string fullName)
  952. {
  953. if (string.IsNullOrEmpty (fullName))
  954. throw new ArgumentNullOrEmptyException (Argument.fullName.ToString ());
  955. }
  956. public static void CheckStream (object stream)
  957. {
  958. if (stream == null)
  959. throw new ArgumentNullException (Argument.stream.ToString ());
  960. }
  961. public static void CheckWriteSeek (Stream stream)
  962. {
  963. if (!stream.CanWrite || !stream.CanSeek)
  964. throw new ArgumentException ("Stream must be writable and seekable.");
  965. }
  966. public static void CheckReadSeek (Stream stream)
  967. {
  968. if (!stream.CanRead || !stream.CanSeek)
  969. throw new ArgumentException ("Stream must be readable and seekable.");
  970. }
  971. public static void CheckType (object type)
  972. {
  973. if (type == null)
  974. throw new ArgumentNullException (Argument.type.ToString ());
  975. }
  976. public static void CheckType (object type, Argument argument)
  977. {
  978. if (type == null)
  979. throw new ArgumentNullException (argument.ToString ());
  980. }
  981. public static void CheckField (object field)
  982. {
  983. if (field == null)
  984. throw new ArgumentNullException (Argument.field.ToString ());
  985. }
  986. public static void CheckMethod (object method)
  987. {
  988. if (method == null)
  989. throw new ArgumentNullException (Argument.method.ToString ());
  990. }
  991. public static void CheckParameters (object parameters)
  992. {
  993. if (parameters == null)
  994. throw new ArgumentNullException (Argument.parameters.ToString ());
  995. }
  996. public static uint GetTimestamp ()
  997. {
  998. return (uint) DateTime.UtcNow.Subtract (new DateTime (1970, 1, 1)).TotalSeconds;
  999. }
  1000. public static bool HasImage (this ModuleDefinition self)
  1001. {
  1002. return self != null && self.HasImage;
  1003. }
  1004. public static string GetFileName (this Stream self)
  1005. {
  1006. var file_stream = self as FileStream;
  1007. if (file_stream == null)
  1008. return string.Empty;
  1009. return Path.GetFullPath (file_stream.Name);
  1010. }
  1011. public static TargetRuntime ParseRuntime (this string self)
  1012. {
  1013. if (string.IsNullOrEmpty (self))
  1014. return TargetRuntime.Net_4_0;
  1015. switch (self [1]) {
  1016. case '1':
  1017. return self [3] == '0'
  1018. ? TargetRuntime.Net_1_0
  1019. : TargetRuntime.Net_1_1;
  1020. case '2':
  1021. return TargetRuntime.Net_2_0;
  1022. case '4':
  1023. default:
  1024. return TargetRuntime.Net_4_0;
  1025. }
  1026. }
  1027. public static string RuntimeVersionString (this TargetRuntime runtime)
  1028. {
  1029. switch (runtime) {
  1030. case TargetRuntime.Net_1_0:
  1031. return "v1.0.3705";
  1032. case TargetRuntime.Net_1_1:
  1033. return "v1.1.4322";
  1034. case TargetRuntime.Net_2_0:
  1035. return "v2.0.50727";
  1036. case TargetRuntime.Net_4_0:
  1037. default:
  1038. return "v4.0.30319";
  1039. }
  1040. }
  1041. public static bool IsWindowsMetadata (this ModuleDefinition module)
  1042. {
  1043. return module.MetadataKind != MetadataKind.Ecma335;
  1044. }
  1045. public static byte [] ReadAll (this Stream self)
  1046. {
  1047. int read;
  1048. var memory = new MemoryStream ((int) self.Length);
  1049. var buffer = new byte [1024];
  1050. while ((read = self.Read (buffer, 0, buffer.Length)) != 0)
  1051. memory.Write (buffer, 0, read);
  1052. return memory.ToArray ();
  1053. }
  1054. public static void Read (object o)
  1055. {
  1056. }
  1057. }
  1058. }