MDRefScopeElems.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. /*
  2. * PERWAPI - An API for Reading and Writing PE Files
  3. *
  4. * Copyright (c) Diane Corney, Queensland University of Technology, 2004.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the PERWAPI Copyright as included with this
  8. * distribution in the file PERWAPIcopyright.rtf.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY as is explained in the copyright notice.
  12. *
  13. * The author may be contacted at d.corney@qut.edu.au
  14. *
  15. * Version Date: 26/01/07
  16. */
  17. using System;
  18. using System.IO;
  19. using System.Collections;
  20. using System.Security.Cryptography;
  21. namespace QUT.PERWAPI
  22. {
  23. /**************************************************************************/
  24. /// <summary>
  25. /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)
  26. /// </summary>
  27. public abstract class ResolutionScope : MetaDataElement
  28. {
  29. internal protected uint nameIx = 0;
  30. internal protected string name;
  31. internal protected ArrayList classes = new ArrayList();
  32. internal protected bool readAsDef = false;
  33. /*-------------------- Constructors ---------------------------------*/
  34. internal ResolutionScope(string name)
  35. {
  36. this.name = name;
  37. }
  38. internal virtual void AddToClassList(Class aClass)
  39. {
  40. classes.Add(aClass);
  41. }
  42. internal Class GetExistingClass(string nameSpace, string name)
  43. {
  44. for (int i = 0; i < classes.Count; i++)
  45. {
  46. Class aClass = (Class)classes[i];
  47. if ((aClass.Name() == name) && (aClass.NameSpace() == nameSpace))
  48. return aClass;
  49. }
  50. return null;
  51. }
  52. protected Class GetClass(string nameSpace, string name, bool both)
  53. {
  54. for (int i = 0; i < classes.Count; i++)
  55. {
  56. Object aClass = classes[i];
  57. if ((((Class)aClass).Name() == name) &&
  58. (!both || (both && (((Class)aClass).NameSpace() == nameSpace))))
  59. return (Class)aClass;
  60. }
  61. return null;
  62. }
  63. /// <summary>
  64. /// Delete a class from this module
  65. /// </summary>
  66. /// <param name="aClass">The name of the class to be deleted</param>
  67. public void RemoveClass(Class aClass)
  68. {
  69. classes.Remove(aClass);
  70. }
  71. /// <summary>
  72. /// Delete the class at an index in the class array
  73. /// </summary>
  74. /// <param name="ix">The index of the class to be deleted (from 0)</param>
  75. public void RemoveClass(int ix)
  76. {
  77. classes.RemoveAt(ix);
  78. }
  79. public string Name() { return name; }
  80. internal override string NameString() { return "[" + name + "]"; }
  81. }
  82. /**************************************************************************/
  83. /// <summary>
  84. /// A scope for descriptors which are referenced
  85. /// </summary>
  86. public abstract class ReferenceScope : ResolutionScope
  87. {
  88. /// <summary>
  89. /// A default class decriptor for globals
  90. /// </summary>
  91. protected ClassRef defaultClass;
  92. /*-------------------- Constructors ---------------------------------*/
  93. internal ReferenceScope(string name)
  94. : base(name)
  95. {
  96. defaultClass = new ClassRef(this, "", "");
  97. defaultClass.MakeSpecial();
  98. }
  99. internal void ReadAsDef()
  100. {
  101. readAsDef = true;
  102. }
  103. internal ClassRef GetDefaultClass() { return defaultClass; }
  104. internal void SetDefaultClass(ClassRef dClass)
  105. {
  106. defaultClass = dClass;
  107. }
  108. internal override void AddToClassList(Class aClass)
  109. {
  110. ((ClassRef)aClass).SetScope(this);
  111. classes.Add(aClass);
  112. }
  113. internal void ReplaceClass(Class aClass)
  114. {
  115. bool found = false;
  116. for (int i = 0; (i < classes.Count) && !found; i++)
  117. {
  118. if (((Class)classes[i]).Name() == aClass.Name())
  119. {
  120. found = true;
  121. }
  122. }
  123. if (!found)
  124. classes.Add(aClass);
  125. }
  126. internal bool isDefaultClass(ClassRef aClass) { return aClass == defaultClass; }
  127. /// <summary>
  128. /// Add a class to this Scope. If this class already exists, throw
  129. /// an exception
  130. /// </summary>
  131. /// <param name="newClass">The class to be added</param>
  132. public void AddClass(ClassRef newClass)
  133. {
  134. ClassRef aClass = (ClassRef)GetClass(newClass.NameSpace(), newClass.Name(), true);
  135. if (aClass != null)
  136. throw new DescriptorException("Class " + newClass.NameString());
  137. if (Diag.DiagOn) Console.WriteLine("Adding class " + newClass.Name() + " to ResolutionScope " + name);
  138. classes.Add(newClass);
  139. // Change Refs to Defs here
  140. newClass.SetScope(this);
  141. }
  142. /// <summary>
  143. /// Add a class to this Scope. If the class already exists,
  144. /// throw an exception.
  145. /// </summary>
  146. /// <param name="nsName">name space name</param>
  147. /// <param name="name">class name</param>
  148. /// <returns>a descriptor for this class in another module</returns>
  149. public virtual ClassRef AddClass(string nsName, string name)
  150. {
  151. ClassRef aClass = GetClass(nsName, name);
  152. if (aClass != null)
  153. {
  154. if ((aClass is SystemClass) && (!((SystemClass)aClass).added))
  155. ((SystemClass)aClass).added = true;
  156. else
  157. throw new DescriptorException("Class " + aClass.NameString());
  158. }
  159. else
  160. {
  161. aClass = new ClassRef(this, nsName, name);
  162. classes.Add(aClass);
  163. }
  164. return aClass;
  165. }
  166. /// <summary>
  167. /// Add a value class to this scope. If the class already exists,
  168. /// throw an exception.
  169. /// </summary>
  170. /// <param name="nsName">name space name</param>
  171. /// <param name="name">class name</param>
  172. /// <returns></returns>
  173. public virtual ClassRef AddValueClass(string nsName, string name)
  174. {
  175. ClassRef aClass = AddClass(nsName, name);
  176. aClass.MakeValueClass();
  177. return aClass;
  178. }
  179. /// <summary>
  180. /// Get a class of this scope, if it exists.
  181. /// </summary>
  182. /// <param name="name">The name of the class.</param>
  183. /// <returns>ClassRef for "name".</returns>
  184. public ClassRef GetClass(string name)
  185. {
  186. return (ClassRef)GetClass(null, name, false);
  187. }
  188. /// <summary>
  189. /// Get a class of this scope, if it exists.
  190. /// </summary>
  191. /// <param name="nsName">The namespace of the class.</param>
  192. /// <param name="name">The name of the class.</param>
  193. /// <returns>ClassRef for "nsName.name".</returns>
  194. public ClassRef GetClass(string nsName, string name)
  195. {
  196. return (ClassRef)GetClass(nsName, name, true);
  197. }
  198. /// <summary>
  199. /// Get all the classes in this scope.
  200. /// </summary>
  201. /// <returns>An array of all the classes in this scope.</returns>
  202. public ClassRef[] GetClasses()
  203. {
  204. return (ClassRef[])classes.ToArray(typeof(ClassRef));
  205. }
  206. /// <summary>
  207. /// Fetch a MethodRef descriptor for the method "retType name (pars)".
  208. /// If one exists, it is returned, else one is created.
  209. /// </summary>
  210. /// <param name="name">method name</param>
  211. /// <param name="retType">return type</param>
  212. /// <param name="pars">method parameter types</param>
  213. /// <returns>a descriptor for this method in anther module</returns>
  214. public MethodRef AddMethod(string name, Type retType, Type[] pars)
  215. {
  216. MethodRef meth = defaultClass.AddMethod(name, retType, pars);
  217. return meth;
  218. }
  219. /// <summary>
  220. /// Fetch a MethodRef descriptor for the method "retType name (pars, optPars)".
  221. /// If one exists, it is returned, else one is created.
  222. /// </summary>
  223. /// <param name="name">method name</param>
  224. /// <param name="retType">return type</param>
  225. /// <param name="pars">parameter types</param>
  226. /// <param name="optPars">optional param types for this vararg method</param>
  227. /// <returns>a descriptor for this method</returns>
  228. public MethodRef AddVarArgMethod(string name, Type retType, Type[] pars, Type[] optPars)
  229. {
  230. MethodRef meth = defaultClass.AddVarArgMethod(name, retType, pars, optPars);
  231. return meth;
  232. }
  233. /// <summary>
  234. /// Add a method to this scope.
  235. /// </summary>
  236. /// <param name="meth">The method to be added.</param>
  237. public void AddMethod(MethodRef meth)
  238. {
  239. defaultClass.AddMethod(meth);
  240. }
  241. // internal void CheckAddMethod(MethodRef meth) {
  242. // defaultClass.CheckAddMethod(meth);
  243. // }
  244. /*
  245. internal void CheckAddMethods(ArrayList meths) {
  246. for (int i=0; i < meths.Count; i++) {
  247. Method meth = (Method)meths[i];
  248. defaultClass.CheckAddMethod(meth);
  249. meth.SetParent(this);
  250. }
  251. }
  252. internal MethodRef GetMethod(string name, uint sigIx) {
  253. return defaultClass.GetMethod(name,sigIx);
  254. }
  255. */
  256. /// <summary>
  257. /// Get a method of this scope, if it exists.
  258. /// </summary>
  259. /// <param name="name">The name of the method.</param>
  260. /// <returns>MethodRef for "name", or null if none exists.</returns>
  261. public MethodRef GetMethod(string name)
  262. {
  263. return defaultClass.GetMethod(name);
  264. }
  265. /// <summary>
  266. /// Get all the methods with a specified name in this scope.
  267. /// </summary>
  268. /// <param name="name">The name of the method(s).</param>
  269. /// <returns>An array of all the methods called "name".</returns>
  270. public MethodRef[] GetMethods(string name)
  271. {
  272. return defaultClass.GetMethods(name);
  273. }
  274. /// <summary>
  275. /// Get a method of this scope, if it exists.
  276. /// </summary>
  277. /// <param name="name">The name of the method</param>
  278. /// <param name="parTypes">The signature of the method.</param>
  279. /// <returns>MethodRef for name(parTypes).</returns>
  280. public MethodRef GetMethod(string name, Type[] parTypes)
  281. {
  282. return defaultClass.GetMethod(name, parTypes);
  283. }
  284. /// <summary>
  285. /// Get a vararg method of this scope, if it exists.
  286. /// </summary>
  287. /// <param name="name">The name of the method.</param>
  288. /// <param name="parTypes">The signature of the method.</param>
  289. /// <param name="optPars">The optional parameters of the vararg method.</param>
  290. /// <returns>MethodRef for name(parTypes,optPars).</returns>
  291. public MethodRef GetMethod(string name, Type[] parTypes, Type[] optPars)
  292. {
  293. return defaultClass.GetMethod(name, parTypes, optPars);
  294. }
  295. /// <summary>
  296. /// Get all the methods in this module
  297. /// </summary>
  298. /// <returns>Array of the methods of this module</returns>
  299. public MethodRef[] GetMethods()
  300. {
  301. return defaultClass.GetMethods();
  302. }
  303. /// <summary>
  304. /// Delete a method from this scope.
  305. /// </summary>
  306. /// <param name="meth">The method to be deleted.</param>
  307. public void RemoveMethod(MethodRef meth)
  308. {
  309. defaultClass.RemoveMethod(meth);
  310. }
  311. /// <summary>
  312. /// Delete a method from this scope. If there are multiple methods with
  313. /// the same name, the first on the list will be deleted.
  314. /// </summary>
  315. /// <param name="name">The name of the method to delete.</param>
  316. public void RemoveMethod(string name)
  317. {
  318. defaultClass.RemoveMethod(name);
  319. }
  320. /// <summary>
  321. /// Delete a method from this scope.
  322. /// </summary>
  323. /// <param name="name">The name of the method to be deleted.</param>
  324. /// <param name="parTypes">The signature of the method to be deleted.</param>
  325. public void RemoveMethod(string name, Type[] parTypes)
  326. {
  327. defaultClass.RemoveMethod(name, parTypes);
  328. }
  329. /// <summary>
  330. /// Delete a (vararg) method from this scope.
  331. /// </summary>
  332. /// <param name="name">The name of the method to be deleted.</param>
  333. /// <param name="parTypes">The signature of the method to be deleted.</param>
  334. /// <param name="optTypes">The optional parameters of the vararg method.</param>
  335. public void RemoveMethod(string name, Type[] parTypes, Type[] optTypes)
  336. {
  337. defaultClass.RemoveMethod(name, parTypes, optTypes);
  338. }
  339. /// <summary>
  340. /// Delete a method from this scope.
  341. /// </summary>
  342. /// <param name="index">The index of the method to be deleted. Index
  343. /// into array returned by GetMethods().</param>
  344. public void RemoveMethod(int index)
  345. {
  346. defaultClass.RemoveMethod(index);
  347. }
  348. /// <summary>
  349. /// Add a field to this scope.
  350. /// </summary>
  351. /// <param name="name">field name</param>
  352. /// <param name="fType">field type</param>
  353. /// <returns>a descriptor for the field "name" in this scope</returns>
  354. public FieldRef AddField(string name, Type fType)
  355. {
  356. FieldRef field = defaultClass.AddField(name, fType);
  357. return field;
  358. }
  359. /// <summary>
  360. /// Add a field to this scope.
  361. /// </summary>
  362. /// <param name="fld">The field to be added</param>
  363. public void AddField(FieldRef fld)
  364. {
  365. defaultClass.AddField(fld);
  366. }
  367. /// <summary>
  368. /// Add a number of fields to this scope.
  369. /// </summary>
  370. /// <param name="flds">The fields to be added.</param>
  371. internal void AddFields(ArrayList flds)
  372. {
  373. for (int i = 0; i < flds.Count; i++)
  374. {
  375. FieldRef fld = (FieldRef)flds[i];
  376. defaultClass.AddField(fld);
  377. }
  378. }
  379. /// <summary>
  380. /// Fetch the FieldRef descriptor for the field "name" in this module,
  381. /// if one exists
  382. /// </summary>
  383. /// <param name="name">field name</param>
  384. /// <returns>FieldRef descriptor for "name" or null</returns>
  385. public FieldRef GetField(string name)
  386. {
  387. return defaultClass.GetField(name);
  388. }
  389. /// <summary>
  390. /// Get all the fields of this module
  391. /// </summary>
  392. /// <returns>Array of FieldRefs for this module</returns>
  393. public FieldRef[] GetFields()
  394. {
  395. return defaultClass.GetFields();
  396. }
  397. internal void AddToMethodList(MethodRef meth)
  398. {
  399. defaultClass.AddToMethodList(meth);
  400. }
  401. internal void AddToFieldList(FieldRef fld)
  402. {
  403. defaultClass.AddToFieldList(fld);
  404. }
  405. internal MethodRef GetMethod(MethSig mSig)
  406. {
  407. return (MethodRef)defaultClass.GetMethod(mSig);
  408. }
  409. }
  410. /**************************************************************************/
  411. /// <summary>
  412. /// A reference to an external assembly (.assembly extern)
  413. /// </summary>
  414. public class AssemblyRef : ReferenceScope
  415. {
  416. private ushort major, minor, build, revision;
  417. uint flags, keyIx, hashIx, cultIx;
  418. bool hasVersion = false, isKeyToken = false;
  419. byte[] keyBytes, hashBytes;
  420. string culture;
  421. /*-------------------- Constructors ---------------------------------*/
  422. internal AssemblyRef(string name)
  423. : base(name)
  424. {
  425. tabIx = MDTable.AssemblyRef;
  426. }
  427. internal AssemblyRef(string name, ushort maj, ushort min, ushort bldNo, ushort rev,
  428. uint flags, byte[] kBytes, string cult, byte[] hBytes)
  429. : base(name)
  430. {
  431. tabIx = MDTable.AssemblyRef;
  432. major = maj;
  433. minor = min;
  434. build = bldNo;
  435. revision = rev;
  436. this.flags = flags; // check
  437. keyBytes = kBytes; // need to set is token or full key
  438. if (keyBytes != null)
  439. isKeyToken = keyBytes.Length <= 8;
  440. culture = cult;
  441. hashBytes = hBytes;
  442. tabIx = MDTable.AssemblyRef;
  443. }
  444. internal static AssemblyRef Read(PEReader buff)
  445. {
  446. ushort majVer = buff.ReadUInt16();
  447. ushort minVer = buff.ReadUInt16();
  448. ushort bldNo = buff.ReadUInt16();
  449. ushort revNo = buff.ReadUInt16();
  450. uint flags = buff.ReadUInt32();
  451. byte[] pKey = buff.GetBlob();
  452. string name = buff.GetString();
  453. string cult = buff.GetString();
  454. byte[] hBytes = buff.GetBlob();
  455. AssemblyRef assemRef;
  456. if (name.ToLower() == "mscorlib")
  457. {
  458. assemRef = MSCorLib.mscorlib;
  459. assemRef.AddVersionInfo(majVer, minVer, bldNo, revNo);
  460. assemRef.AddHash(hBytes);
  461. if (pKey.Length > 8) assemRef.AddKey(pKey);
  462. else assemRef.AddKeyToken(pKey);
  463. assemRef.AddCulture(cult);
  464. assemRef.SetFlags(flags);
  465. }
  466. else
  467. {
  468. assemRef = new AssemblyRef(name, majVer, minVer, bldNo, revNo, flags, pKey, cult, hBytes);
  469. }
  470. return assemRef;
  471. }
  472. internal static void Read(PEReader buff, TableRow[] table)
  473. {
  474. for (int i = 0; i < table.Length; i++)
  475. table[i] = Read(buff);
  476. }
  477. /*------------------------- public set and get methods --------------------------*/
  478. /// <summary>
  479. /// Add version information about this external assembly
  480. /// </summary>
  481. /// <param name="majVer">Major Version</param>
  482. /// <param name="minVer">Minor Version</param>
  483. /// <param name="bldNo">Build Number</param>
  484. /// <param name="revNo">Revision Number</param>
  485. public void AddVersionInfo(int majVer, int minVer, int bldNo, int revNo)
  486. {
  487. major = (ushort)majVer;
  488. minor = (ushort)minVer;
  489. build = (ushort)bldNo;
  490. revision = (ushort)revNo;
  491. hasVersion = true;
  492. }
  493. /// <summary>
  494. /// Get the major version for this external assembly
  495. /// </summary>
  496. /// <returns>major version number</returns>
  497. public int MajorVersion() { return major; }
  498. /// <summary>
  499. /// Get the minor version for this external assembly
  500. /// </summary>
  501. /// <returns>minor version number</returns>
  502. public int MinorVersion() { return minor; }
  503. /// <summary>
  504. /// Get the build number for this external assembly
  505. /// </summary>
  506. /// <returns>build number</returns>
  507. public int BuildNumber() { return build; }
  508. /// <summary>
  509. /// Get the revision number for this external assembly
  510. /// </summary>
  511. /// <returns>revision number</returns>
  512. public int RevisionNumber() { return revision; }
  513. /// <summary>
  514. /// Check if this external assembly has any version information
  515. /// </summary>
  516. public bool HasVersionInfo() { return hasVersion; }
  517. /// <summary>
  518. /// Add the hash value for this external assembly
  519. /// </summary>
  520. /// <param name="hash">bytes of the hash value</param>
  521. public void AddHash(byte[] hash) { hashBytes = hash; }
  522. /// <summary>
  523. /// Get the hash value for this external assembly
  524. /// </summary>
  525. /// <returns></returns>
  526. public byte[] GetHash() { return hashBytes; }
  527. /// <summary>
  528. /// Set the culture for this external assembly
  529. /// </summary>
  530. /// <param name="cult">the culture string</param>
  531. public void AddCulture(string cult) { culture = cult; }
  532. public string GetCulture() { return culture; }
  533. /// <summary>
  534. /// Add the full public key for this external assembly
  535. /// </summary>
  536. /// <param name="key">bytes of the public key</param>
  537. public void AddKey(byte[] key)
  538. {
  539. flags |= 0x0001; // full public key
  540. keyBytes = key;
  541. }
  542. /// <summary>
  543. /// Add the public key token (low 8 bytes of the public key)
  544. /// </summary>
  545. /// <param name="key">low 8 bytes of public key</param>
  546. public void AddKeyToken(byte[] key)
  547. {
  548. keyBytes = key;
  549. isKeyToken = true;
  550. }
  551. /// <summary>
  552. /// Get the public key token
  553. /// </summary>
  554. /// <returns>bytes of public key</returns>
  555. public byte[] GetKey() { return keyBytes; }
  556. /// <summary>
  557. /// Make an AssemblyRef for "name".
  558. /// </summary>
  559. /// <param name="name">The name of the assembly</param>
  560. /// <returns>AssemblyRef for "name".</returns>
  561. public static AssemblyRef MakeAssemblyRef(string name)
  562. {
  563. AssemblyRef assemRef = new AssemblyRef(name);
  564. return assemRef;
  565. }
  566. public static AssemblyRef MakeAssemblyRef(
  567. string name,
  568. int majVer,
  569. int minVer,
  570. int bldNum,
  571. int revNum,
  572. byte[] key)
  573. {
  574. AssemblyRef assemRef = new AssemblyRef(name);
  575. assemRef.AddVersionInfo(majVer, minVer, bldNum, revNum);
  576. if (key.Length > 8)
  577. assemRef.AddKey(key);
  578. else
  579. assemRef.AddKeyToken(key);
  580. return assemRef;
  581. }
  582. /*------------------------ internal functions ----------------------------*/
  583. internal void SetFlags(uint flags)
  584. {
  585. this.flags = flags;
  586. }
  587. internal string AssemblyString()
  588. {
  589. string result = name;
  590. if (hasVersion)
  591. result = result + ", Version=" + major + "." + minor + "." +
  592. build + "." + revision;
  593. if (keyBytes != null)
  594. {
  595. string tokenStr = "=";
  596. if (isKeyToken) tokenStr = "Token=";
  597. result = result + ", PublicKey" + tokenStr;
  598. for (int i = 0; i < keyBytes.Length; i++)
  599. {
  600. result = result + Hex.Byte(keyBytes[i]);
  601. }
  602. }
  603. if (culture != null)
  604. result = result + ", Culture=" + culture;
  605. return result;
  606. }
  607. internal static uint Size(MetaData md)
  608. {
  609. return 12 + 2 * md.StringsIndexSize() + 2 * md.BlobIndexSize();
  610. }
  611. internal sealed override void BuildTables(MetaDataOut md)
  612. {
  613. md.AddToTable(MDTable.AssemblyRef, this);
  614. keyIx = md.AddToBlobHeap(keyBytes);
  615. nameIx = md.AddToStringsHeap(name);
  616. cultIx = md.AddToStringsHeap(culture);
  617. hashIx = md.AddToBlobHeap(hashBytes);
  618. }
  619. internal sealed override void Write(PEWriter output)
  620. {
  621. output.Write(major);
  622. output.Write(minor);
  623. output.Write(build);
  624. output.Write(revision);
  625. output.Write(flags);
  626. output.BlobIndex(keyIx);
  627. output.StringsIndex(nameIx);
  628. output.StringsIndex(cultIx);
  629. output.BlobIndex(hashIx);
  630. }
  631. internal override void Write(CILWriter output)
  632. {
  633. output.WriteLine(".assembly extern " + name + " { }");
  634. }
  635. internal sealed override uint GetCodedIx(CIx code)
  636. {
  637. switch (code)
  638. {
  639. case (CIx.ResolutionScope): return 2;
  640. case (CIx.HasCustomAttr): return 15;
  641. case (CIx.Implementation): return 1;
  642. }
  643. return 0;
  644. }
  645. }
  646. /**************************************************************************/
  647. /// <summary>
  648. /// The assembly for mscorlib.
  649. /// </summary>
  650. public sealed class MSCorLib : AssemblyRef
  651. {
  652. internal static MSCorLib mscorlib = new MSCorLib();
  653. internal SystemClass ObjectClass;
  654. private ClassRef valueType;
  655. internal MSCorLib()
  656. : base("mscorlib")
  657. {
  658. classes.Add(new SystemClass(this, PrimitiveType.Void));
  659. classes.Add(new SystemClass(this, PrimitiveType.Boolean));
  660. classes.Add(new SystemClass(this, PrimitiveType.Char));
  661. classes.Add(new SystemClass(this, PrimitiveType.Int8));
  662. classes.Add(new SystemClass(this, PrimitiveType.UInt8));
  663. classes.Add(new SystemClass(this, PrimitiveType.Int16));
  664. classes.Add(new SystemClass(this, PrimitiveType.UInt16));
  665. classes.Add(new SystemClass(this, PrimitiveType.Int32));
  666. classes.Add(new SystemClass(this, PrimitiveType.UInt32));
  667. classes.Add(new SystemClass(this, PrimitiveType.Int64));
  668. classes.Add(new SystemClass(this, PrimitiveType.UInt64));
  669. classes.Add(new SystemClass(this, PrimitiveType.Float32));
  670. classes.Add(new SystemClass(this, PrimitiveType.Float64));
  671. classes.Add(new SystemClass(this, PrimitiveType.IntPtr));
  672. classes.Add(new SystemClass(this, PrimitiveType.UIntPtr));
  673. classes.Add(new SystemClass(this, PrimitiveType.String));
  674. classes.Add(new SystemClass(this, PrimitiveType.TypedRef));
  675. ObjectClass = new SystemClass(this, PrimitiveType.Object);
  676. classes.Add(ObjectClass);
  677. valueType = new ClassRef(this, "System", "ValueType");
  678. valueType.MakeValueClass();
  679. classes.Add(valueType);
  680. }
  681. internal ClassRef ValueType()
  682. {
  683. return valueType;
  684. }
  685. }
  686. /**************************************************************************/
  687. /// <summary>
  688. /// Descriptor for a module in an assembly
  689. /// </summary>
  690. public class ModuleRef : ReferenceScope
  691. {
  692. ArrayList exportedClasses = new ArrayList();
  693. internal ModuleFile modFile;
  694. internal Module defOf;
  695. internal bool ismscorlib = false;
  696. /*-------------------- Constructors ---------------------------------*/
  697. internal ModuleRef(string name, bool entryPoint, byte[] hashValue)
  698. : base(name)
  699. {
  700. modFile = new ModuleFile(name, hashValue, entryPoint);
  701. ismscorlib = name.ToLower() == "mscorlib.dll";
  702. tabIx = MDTable.ModuleRef;
  703. }
  704. internal ModuleRef(string name)
  705. : base(name)
  706. {
  707. ismscorlib = name.ToLower() == "mscorlib.dll";
  708. tabIx = MDTable.ModuleRef;
  709. }
  710. internal ModuleRef(ModuleFile file)
  711. : base(file.Name())
  712. {
  713. modFile = file;
  714. tabIx = MDTable.ModuleRef;
  715. }
  716. internal static void Read(PEReader buff, TableRow[] mods, bool resolve)
  717. {
  718. for (int i = 0; i < mods.Length; i++)
  719. {
  720. string name = buff.GetString();
  721. ModuleRef mRef = new ModuleRef(name);
  722. if (resolve) mRef.modFile = buff.GetFileDesc(name);
  723. mods[i] = mRef;
  724. }
  725. }
  726. internal sealed override void Resolve(PEReader buff)
  727. {
  728. modFile = buff.GetFileDesc(name);
  729. if (modFile != null)
  730. modFile.fileModule = this;
  731. }
  732. /*------------------------- public set and get methods --------------------------*/
  733. /// <summary>
  734. /// Add a class which is declared public in this external module of
  735. /// THIS assembly. This class will be exported from this assembly.
  736. /// The ilasm syntax for this is .extern class
  737. /// </summary>
  738. /// <param name="attrSet">attributes of the class to be exported</param>
  739. /// <param name="nsName">name space name</param>
  740. /// <param name="name">external class name</param>
  741. /// <param name="declFile">the file where the class is declared</param>
  742. /// <param name="isValueClass">is this class a value type?</param>
  743. /// <returns>a descriptor for this external class</returns>
  744. public ClassRef AddExternClass(TypeAttr attrSet, string nsName,
  745. string name, bool isValueClass, PEFile pefile)
  746. {
  747. ClassRef cRef = new ClassRef(this, nsName, name);
  748. if (isValueClass) cRef.MakeValueClass();
  749. ExternClass eClass = new ExternClass(attrSet, nsName, name, modFile);
  750. exportedClasses.Add(eClass);
  751. cRef.SetExternClass(eClass);
  752. classes.Add(cRef);
  753. return cRef;
  754. }
  755. public static ModuleRef MakeModuleRef(string name, bool entryPoint, byte[] hashValue)
  756. {
  757. ModuleRef mRef = new ModuleRef(name, entryPoint, hashValue);
  758. return mRef;
  759. }
  760. public void SetEntryPoint()
  761. {
  762. modFile.SetEntryPoint();
  763. }
  764. public void SetHash(byte[] hashVal)
  765. {
  766. modFile.SetHash(hashVal);
  767. }
  768. /*------------------------- internal functions --------------------------*/
  769. /* internal void AddMember(Member memb) {
  770. if (memb is Method) {
  771. Method existing = GetMethod(memb.Name(),((Method)memb).GetParTypes());
  772. if (existing == null)
  773. methods.Add(memb);
  774. } else {
  775. Field existing = GetField(memb.Name());
  776. if (existing == null)
  777. fields.Add(memb);
  778. }
  779. }
  780. */
  781. internal void AddToExportedClassList(ClassRef exClass)
  782. {
  783. if (exportedClasses.Contains(exClass)) return;
  784. exportedClasses.Add(exClass);
  785. }
  786. internal void AddExternClass(ExternClass eClass)
  787. {
  788. exportedClasses.Add(eClass);
  789. }
  790. internal static uint Size(MetaData md)
  791. {
  792. return md.StringsIndexSize();
  793. }
  794. internal sealed override void BuildTables(MetaDataOut md)
  795. {
  796. md.AddToTable(MDTable.ModuleRef, this);
  797. nameIx = md.AddToStringsHeap(name);
  798. if (modFile != null) modFile.BuildMDTables(md);
  799. for (int i = 0; i < exportedClasses.Count; i++)
  800. ((ExternClass)exportedClasses[i]).BuildMDTables(md);
  801. }
  802. internal sealed override void Write(PEWriter output)
  803. {
  804. output.StringsIndex(nameIx);
  805. }
  806. internal sealed override uint GetCodedIx(CIx code)
  807. {
  808. switch (code)
  809. {
  810. case (CIx.HasCustomAttr): return 12;
  811. case (CIx.MemberRefParent): return 2;
  812. case (CIx.ResolutionScope): return 1;
  813. }
  814. return 0;
  815. }
  816. }
  817. }