ilMetaReader.ml 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406
  1. (*
  2. * This file is part of ilLib
  3. * Copyright (c)2004-2013 Haxe Foundation
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  18. *)
  19. open PeData;;
  20. open PeReader;;
  21. open IlMeta;;
  22. open IO;;
  23. open Printf;;
  24. open IlMetaTools;;
  25. open ExtString;;
  26. open IlData;;
  27. (* *)
  28. let get_field = function
  29. | Field f -> f
  30. | _ -> assert false
  31. let get_method = function
  32. | Method m -> m
  33. | _ -> assert false
  34. let get_param = function
  35. | Param p -> p
  36. | _ -> assert false
  37. let get_type_def = function
  38. | TypeDef p -> p
  39. | _ -> assert false
  40. let get_event = function
  41. | Event e -> e
  42. | _ -> assert false
  43. let get_property = function
  44. | Property p -> p
  45. | _ -> assert false
  46. let get_module_ref = function
  47. | ModuleRef r -> r
  48. | _ -> assert false
  49. let get_assembly_ref = function
  50. | AssemblyRef r -> r
  51. | _ -> assert false
  52. let get_generic_param = function
  53. | GenericParam p -> p
  54. | _ -> assert false
  55. (* decoding helpers *)
  56. let type_def_vis_of_int i = match i land 0x7 with
  57. (* visibility flags - mask 0x7 *)
  58. | 0x0 -> VPrivate (* 0x0 *)
  59. | 0x1 -> VPublic (* 0x1 *)
  60. | 0x2 -> VNestedPublic (* 0x2 *)
  61. | 0x3 -> VNestedPrivate (* 0x3 *)
  62. | 0x4 -> VNestedFamily (* 0x4 *)
  63. | 0x5 -> VNestedAssembly (* 0x5 *)
  64. | 0x6 -> VNestedFamAndAssem (* 0x6 *)
  65. | 0x7 -> VNestedFamOrAssem (* 0x7 *)
  66. | _ -> assert false
  67. let type_def_layout_of_int i = match i land 0x18 with
  68. (* layout flags - mask 0x18 *)
  69. | 0x0 -> LAuto (* 0x0 *)
  70. | 0x8 -> LSequential (* 0x8 *)
  71. | 0x10 -> LExplicit (* 0x10 *)
  72. | _ -> assert false
  73. let type_def_semantics_of_int iprops = List.fold_left (fun acc i ->
  74. if (iprops land i) = i then (match i with
  75. (* semantics flags - mask 0x5A0 *)
  76. | 0x20 -> SInterface (* 0x20 *)
  77. | 0x80 -> SAbstract (* 0x80 *)
  78. | 0x100 -> SSealed (* 0x100 *)
  79. | 0x400 -> SSpecialName (* 0x400 *)
  80. | _ -> assert false) :: acc
  81. else
  82. acc) [] [0x20;0x80;0x100;0x400]
  83. let type_def_impl_of_int iprops = List.fold_left (fun acc i ->
  84. if (iprops land i) = i then (match i with
  85. (* type implementation flags - mask 0x103000 *)
  86. | 0x1000 -> IImport (* 0x1000 *)
  87. | 0x2000 -> ISerializable (* 0x2000 *)
  88. | 0x00100000 -> IBeforeFieldInit (* 0x00100000 *)
  89. | _ -> assert false) :: acc
  90. else
  91. acc) [] [0x1000;0x2000;0x00100000]
  92. let type_def_string_of_int i = match i land 0x00030000 with
  93. (* string formatting flags - mask 0x00030000 *)
  94. | 0x0 -> SAnsi (* 0x0 *)
  95. | 0x00010000 -> SUnicode (* 0x00010000 *)
  96. | 0x00020000 -> SAutoChar (* 0x00020000 *)
  97. | _ -> assert false
  98. let type_def_flags_of_int i =
  99. {
  100. tdf_vis = type_def_vis_of_int i;
  101. tdf_layout = type_def_layout_of_int i;
  102. tdf_semantics = type_def_semantics_of_int i;
  103. tdf_impl = type_def_impl_of_int i;
  104. tdf_string = type_def_string_of_int i;
  105. }
  106. let null_type_def_flags = type_def_flags_of_int 0
  107. let field_access_of_int i = match i land 0x07 with
  108. (* access flags - mask 0x07 *)
  109. | 0x0 -> FAPrivateScope (* 0x0 *)
  110. | 0x1 -> FAPrivate (* 0x1 *)
  111. | 0x2 -> FAFamAndAssem (* 0x2 *)
  112. | 0x3 -> FAAssembly (* 0x3 *)
  113. | 0x4 -> FAFamily (* 0x4 *)
  114. | 0x5 -> FAFamOrAssem (* 0x5 *)
  115. | 0x6 -> FAPublic (* 0x6 *)
  116. | _ -> assert false
  117. let field_contract_of_int iprops = List.fold_left (fun acc i ->
  118. if (iprops land i) = i then (match i with
  119. (* contract flags - mask 0x02F0 *)
  120. | 0x10 -> CStatic (* 0x10 *)
  121. | 0x20 -> CInitOnly (* 0x20 *)
  122. | 0x40 -> CLiteral (* 0x40 *)
  123. | 0x80 -> CNotSerialized (* 0x80 *)
  124. | 0x200 -> CSpecialName (* 0x200 *)
  125. | _ -> assert false) :: acc
  126. else
  127. acc) [] [0x10;0x20;0x40;0x80;0x200]
  128. let field_reserved_of_int iprops = List.fold_left (fun acc i ->
  129. if (iprops land i) = i then (match i with
  130. (* reserved flags - cannot be set explicitly. mask 0x9500 *)
  131. | 0x400 -> RSpecialName (* 0x400 *)
  132. | 0x1000 -> RMarshal (* 0x1000 *)
  133. | 0x8000 -> RConstant (* 0x8000 *)
  134. | 0x0100 -> RFieldRVA (* 0x0100 *)
  135. | _ -> assert false) :: acc
  136. else
  137. acc) [] [0x400;0x1000;0x8000;0x100]
  138. let field_flags_of_int i =
  139. {
  140. ff_access = field_access_of_int i;
  141. ff_contract = field_contract_of_int i;
  142. ff_reserved = field_reserved_of_int i;
  143. }
  144. let null_field_flags = field_flags_of_int 0
  145. let method_contract_of_int iprops = List.fold_left (fun acc i ->
  146. if (iprops land i) = i then (match i with
  147. (* contract flags - mask 0xF0 *)
  148. | 0x10 -> CMStatic (* 0x10 *)
  149. | 0x20 -> CMFinal (* 0x20 *)
  150. | 0x40 -> CMVirtual (* 0x40 *)
  151. | 0x80 -> CMHideBySig (* 0x80 *)
  152. | _ -> assert false) :: acc
  153. else
  154. acc) [] [0x10;0x20;0x40;0x80]
  155. let method_vtable_of_int iprops = List.fold_left (fun acc i ->
  156. if (iprops land i) = i then (match i with
  157. (* vtable flags - mask 0x300 *)
  158. | 0x100 -> VNewSlot (* 0x100 *)
  159. | 0x200 -> VStrict (* 0x200 *)
  160. | _ -> assert false) :: acc
  161. else
  162. acc) [] [0x100;0x200]
  163. let method_impl_of_int iprops = List.fold_left (fun acc i ->
  164. if (iprops land i) = i then (match i with
  165. (* implementation flags - mask 0x2C08 *)
  166. | 0x0400 -> IAbstract (* 0x0400 *)
  167. | 0x0800 -> ISpecialName (* 0x0800 *)
  168. | 0x2000 -> IPInvokeImpl (* 0x2000 *)
  169. | 0x0008 -> IUnmanagedExp (* 0x0008 *)
  170. | _ -> assert false) :: acc
  171. else
  172. acc) [] [0x0400;0x0800;0x2000;0x0008]
  173. let method_reserved_of_int iprops = List.fold_left (fun acc i ->
  174. if (iprops land i) = i then (match i with
  175. (* reserved flags - cannot be set explicitly. mask 0xD000 *)
  176. | 0x1000 -> RTSpecialName (* 0x1000 *)
  177. | 0x4000 -> RHasSecurity (* 0x4000 *)
  178. | 0x8000 -> RReqSecObj (* 0x8000 *)
  179. | _ -> assert false) :: acc
  180. else
  181. acc) [] [0x1000;0x4000;0x8000]
  182. let method_code_type_of_int i = match i land 0x3 with
  183. | 0x0 -> CCil (* 0x0 *)
  184. | 0x1 -> CNative (* 0x1 *)
  185. | 0x2 -> COptIl (* 0x2 *)
  186. | 0x3 -> CRuntime (* 0x3 *)
  187. | _ -> assert false
  188. let method_code_mngmt_of_int i = match i land 0x4 with
  189. | 0x0 -> MManaged (* 0x0 *)
  190. | 0x4 -> MUnmanaged (* 0x4 *)
  191. | _ -> assert false
  192. let method_interop_of_int iprops = List.fold_left (fun acc i ->
  193. if (iprops land i) = i then (match i with
  194. | 0x10 -> OForwardRef (* 0x10 *)
  195. | 0x80 -> OPreserveSig (* 0x80 *)
  196. | 0x1000 -> OInternalCall (* 0x1000 *)
  197. | 0x20 -> OSynchronized (* 0x20 *)
  198. | 0x08 -> ONoInlining (* 0x08 *)
  199. | _ -> assert false) :: acc
  200. else
  201. acc) [] [0x10;0x80;0x1000;0x20;0x08]
  202. let method_flags_of_int iflags flags =
  203. {
  204. mf_access = field_access_of_int flags;
  205. mf_contract = method_contract_of_int flags;
  206. mf_vtable = method_vtable_of_int flags;
  207. mf_impl = method_impl_of_int flags;
  208. mf_reserved = method_reserved_of_int flags;
  209. mf_code_type = method_code_type_of_int iflags;
  210. mf_code_mngmt = method_code_mngmt_of_int iflags;
  211. mf_interop = method_interop_of_int iflags;
  212. }
  213. let null_method_flags = method_flags_of_int 0 0
  214. let param_io_of_int iprops = List.fold_left (fun acc i ->
  215. if (iprops land i) = i then (match i with
  216. (* input/output flags - mask 0x13 *)
  217. | 0x1 -> PIn (* 0x1 *)
  218. | 0x2 -> POut (* 0x2 *)
  219. | 0x10 -> POpt (* 0x10 *)
  220. | _ -> assert false) :: acc
  221. else
  222. acc) [] [0x1;0x2;0x10]
  223. let param_reserved_of_int iprops = List.fold_left (fun acc i ->
  224. if (iprops land i) = i then (match i with
  225. (* reserved flags - mask 0xF000 *)
  226. | 0x1000 -> PHasConstant (* 0x1000 *)
  227. | 0x2000 -> PMarshal (* 0x2000 *)
  228. | _ -> assert false) :: acc
  229. else
  230. acc) [] [0x1000;0x2000]
  231. let param_flags_of_int i =
  232. {
  233. pf_io = param_io_of_int i;
  234. pf_reserved = param_reserved_of_int i;
  235. }
  236. let null_param_flags = param_flags_of_int 0
  237. let callconv_of_int ?match_generic_inst:(match_generic_inst=false) i =
  238. let basic = match i land 0xF with
  239. | 0x0 -> CallDefault (* 0x0 *)
  240. | 0x1 -> CallCDecl
  241. | 0x2 -> CallStdCall
  242. | 0x3 -> CallThisCall
  243. | 0x4 -> CallFastCall
  244. | 0x5 -> CallVararg (* 0x5 *)
  245. | 0x6 -> CallField (* 0x6 *)
  246. | 0x7 -> CallLocal (* 0x7 *)
  247. | 0x8 -> CallProp (* 0x8 *)
  248. | 0x9 -> CallUnmanaged (* 0x9 *)
  249. | 0xa when match_generic_inst -> CallGenericInst (* 0xA *)
  250. | i -> printf "error 0x%x\n\n" i; assert false
  251. in
  252. match i land 0x20 with
  253. | 0x20 ->
  254. [CallHasThis;basic]
  255. | _ when i land 0x40 = 0x40 ->
  256. [CallExplicitThis;basic]
  257. | _ -> [basic]
  258. let event_flags_of_int iprops = List.fold_left (fun acc i ->
  259. if (iprops land i) = i then (match i with
  260. | 0x0200 -> ESpecialName (* 0x0200 *)
  261. | 0x0400 -> ERTSpecialName (* 0x0400 *)
  262. | _ -> assert false) :: acc
  263. else
  264. acc) [] [0x0200;0x0400]
  265. let property_flags_of_int iprops = List.fold_left (fun acc i ->
  266. if (iprops land i) = i then (match i with
  267. | 0x0200 -> PSpecialName (* 0x0200 *)
  268. | 0x0400 -> PRTSpecialName (* 0x0400 *)
  269. | 0x1000 -> PHasDefault (* 0x1000 *)
  270. | 0xE9FF -> PUnused (* 0xE9FF *)
  271. | _ -> assert false) :: acc
  272. else
  273. acc) [] [0x0200;0x0400;0x1000;0xE9FF]
  274. let semantic_flags_of_int iprops = List.fold_left (fun acc i ->
  275. if (iprops land i) = i then (match i with
  276. | 0x0001 -> SSetter (* 0x0001 *)
  277. | 0x0002 -> SGetter (* 0x0002 *)
  278. | 0x0004 -> SOther (* 0x0004 *)
  279. | 0x0008 -> SAddOn (* 0x0008 *)
  280. | 0x0010 -> SRemoveOn (* 0x0010 *)
  281. | 0x0020 -> SFire (* 0x0020 *)
  282. | _ -> assert false) :: acc
  283. else
  284. acc) [] [0x0001;0x0002;0x0004;0x0008;0x0010;0x0020]
  285. let impl_charset_of_int = function
  286. | 0x0 -> IDefault (* 0x0 *)
  287. | 0x2 -> IAnsi (* 0x2 *)
  288. | 0x4 -> IUnicode (* 0x4 *)
  289. | 0x6 -> IAutoChar (* 0x6 *)
  290. | _ -> assert false
  291. let impl_callconv_of_int = function
  292. | 0x0 -> IDefaultCall (* 0x0 *)
  293. | 0x100 -> IWinApi (* 0x100 *)
  294. | 0x200 -> ICDecl (* 0x200 *)
  295. | 0x300 -> IStdCall (* 0x300 *)
  296. | 0x400 -> IThisCall (* 0x400 *)
  297. | 0x500 -> IFastCall (* 0x500 *)
  298. | _ -> assert false
  299. let impl_flag_of_int iprops = List.fold_left (fun acc i ->
  300. if (iprops land i) = i then (match i with
  301. | 0x1 -> INoMangle (* 0x1 *)
  302. | 0x10 -> IBestFit (* 0x10 *)
  303. | 0x20 -> IBestFitOff (* 0x20 *)
  304. | 0x40 -> ILastErr (* 0x40 *)
  305. | 0x1000 -> ICharMapError (* 0x1000 *)
  306. | 0x2000 -> ICharMapErrorOff (* 0x2000 *)
  307. | _ -> assert false) :: acc
  308. else
  309. acc) [] [0x1;0x10;0x20;0x40;0x1000;0x2000]
  310. let impl_flags_of_int i =
  311. {
  312. if_charset = impl_charset_of_int (i land 0x6);
  313. if_callconv = impl_callconv_of_int (i land 0x700);
  314. if_flags = impl_flag_of_int i;
  315. }
  316. let null_impl_flags = impl_flags_of_int 0
  317. let assembly_flags_of_int iprops = List.fold_left (fun acc i ->
  318. if (iprops land i) = i then (match i with
  319. | 0x1 -> APublicKey (* 0x1 *)
  320. | 0x100 -> ARetargetable (* 0x100 *)
  321. | 0x4000 -> ADisableJitCompileOptimizer (* 0x4000 *)
  322. | 0x8000 -> AEnableJitCompileTracking (* 0x8000 *)
  323. | _ -> assert false) :: acc
  324. else
  325. acc) [] [0x1;0x100;0x4000;0x8000]
  326. let hash_algo_of_int = function
  327. | 0x0 -> HNone (* 0x0 *)
  328. | 0x8003 -> HReserved (* 0x8003 *)
  329. | 0x8004 -> HSha1 (* 0x8004 *)
  330. | _ -> assert false
  331. let file_flag_of_int = function
  332. | 0x0 -> ContainsMetadata (* 0x0 *)
  333. | 0x1 -> ContainsNoMetadata (* 0x1 *)
  334. | _ -> assert false
  335. let manifest_resource_flag_of_int i = match i land 0x7 with
  336. | 0x0 -> RNone (* 0x0 *)
  337. | 0x1 -> RPublic (* 0x1 *)
  338. | 0x2 -> RPrivate (* 0x2 *)
  339. | _ -> assert false
  340. let generic_variance_of_int = function
  341. (* mask 0x3 *)
  342. | 0x0 -> VNone (* 0x0 *)
  343. | 0x1 -> VCovariant (* 0x1 *)
  344. | 0x2 -> VContravariant (* 0x2 *)
  345. | _ -> assert false
  346. let generic_constraint_of_int iprops = List.fold_left (fun acc i ->
  347. if (iprops land i) = i then (match i with
  348. (* mask 0x1C *)
  349. | 0x4 -> CInstanceType (* 0x4 *)
  350. | 0x8 -> CValueType (* 0x8 *)
  351. | 0x10 -> CDefaultCtor (* 0x10 *)
  352. | _ -> assert false) :: acc
  353. else
  354. acc) [] [0x4;0x8;0x10]
  355. let generic_flags_of_int i =
  356. {
  357. gf_variance = generic_variance_of_int (i land 0x3);
  358. gf_constraint = generic_constraint_of_int (i land 0x1C);
  359. }
  360. let null_generic_flags = generic_flags_of_int 0
  361. (* TODO: convert from string to Bigstring if OCaml 4 is available *)
  362. type meta_ctx = {
  363. compressed : bool;
  364. (* is a compressed stream *)
  365. strings_stream : string;
  366. mutable strings_offset : int;
  367. (* #Strings: a string heap containing the names of metadata items *)
  368. blob_stream : string;
  369. mutable blob_offset : int;
  370. (* #Blob: blob heap containing internal metadata binary object, such as default values, signatures, etc *)
  371. guid_stream : string;
  372. mutable guid_offset : int;
  373. (* #GUID: a GUID heap *)
  374. us_stream : string;
  375. (* #US: user-defined strings *)
  376. meta_stream : string;
  377. (* may be either: *)
  378. (* #~: compressed (optimized) metadata stream *)
  379. (* #-: uncompressed (unoptimized) metadata stream *)
  380. mutable meta_edit_continue : bool;
  381. mutable meta_has_deleted : bool;
  382. module_cache : meta_cache;
  383. tables : (clr_meta DynArray.t) array;
  384. table_sizes : ( string -> int -> int * int ) array;
  385. extra_streams : clr_stream_header list;
  386. relations : (meta_pointer, clr_meta) Hashtbl.t;
  387. typedefs : (ilpath, meta_type_def) Hashtbl.t;
  388. mutable delays : (unit -> unit) list;
  389. }
  390. and meta_cache = {
  391. mutable lookups : (string -> meta_ctx option) list;
  392. mutable mcache : (meta_module * meta_ctx) list;
  393. }
  394. let empty = "<not initialized>"
  395. let create_cache () =
  396. {
  397. lookups = [];
  398. mcache = [];
  399. }
  400. let add_lookup cache fn =
  401. cache.lookups <- fn :: cache.lookups
  402. (* ******* Reading from Strings ********* *)
  403. let sget s pos = Char.code (String.get s pos)
  404. let read_compressed_i32 s pos =
  405. let v = sget s pos in
  406. (* Printf.printf "compressed: %x (18 0x%x 19 0x%x)\n" v (sget s (pos+20)) (sget s (pos+21)); *)
  407. if v land 0x80 = 0x00 then
  408. pos+1, v
  409. else if v land 0xC0 = 0x80 then
  410. pos+2, ((v land 0x3F) lsl 8) lor (sget s (pos+1))
  411. else if v land 0xE0 = 0xC0 then
  412. pos+4, ((v land 0x1F) lsl 24) lor ((sget s (pos+1)) lsl 16) lor ((sget s (pos+2)) lsl 8) lor (sget s (pos+3))
  413. else
  414. error (Printf.sprintf "Error reading compressed data. Invalid first byte: %x" v)
  415. let int_of_table (idx : clr_meta_idx) : int = Obj.magic idx
  416. let table_of_int (idx : int) : clr_meta_idx = Obj.magic idx
  417. let sread_ui8 s pos =
  418. let n1 = sget s pos in
  419. pos+1,n1
  420. let sread_i32 s pos =
  421. let n1 = sget s pos in
  422. let n2 = sget s (pos+1) in
  423. let n3 = sget s (pos+2) in
  424. let n4 = sget s (pos+3) in
  425. pos+4, (n4 lsl 24) lor (n3 lsl 16) lor (n2 lsl 8) lor n1
  426. let sread_real_i32 s pos =
  427. let n1 = sget s pos in
  428. let n2 = sget s (pos+1) in
  429. let n3 = sget s (pos+2) in
  430. let n4 = Int32.of_int (sget s (pos+3)) in
  431. let n = Int32.of_int ((n3 lsl 16) lor (n2 lsl 8) lor n1) in
  432. let n4 = Int32.shift_left n4 24 in
  433. pos+4, (Int32.logor n4 n)
  434. let sread_i64 s pos =
  435. let pos, v1 = sread_real_i32 s (pos+1) in
  436. let v1 = Int64.of_int32 v1 in
  437. let pos, v2 = sread_real_i32 s pos in
  438. let v2 = Int64.of_int32 v2 in
  439. let v2 = Int64.shift_left v2 32 in
  440. pos, (Int64.logor v1 v2)
  441. let sread_ui16 s pos =
  442. let n1 = sget s pos in
  443. let n2 = sget s (pos+1) in
  444. pos+2, (n2 lsl 8) lor n1
  445. let read_cstring ctx pos =
  446. let s = ctx.strings_stream in
  447. let rec loop en =
  448. match String.get s en with
  449. | '\x00' -> en - pos
  450. | _ -> loop (en+1)
  451. in
  452. (* printf "len 0x%x - pos 0x%x\n" (String.length s) pos; *)
  453. let len = loop pos in
  454. String.sub s pos len
  455. let read_sstring_idx ctx pos =
  456. let s = ctx.meta_stream in
  457. let metapos,i = if ctx.strings_offset = 2 then
  458. sread_ui16 s pos
  459. else
  460. sread_i32 s pos
  461. in
  462. match i with
  463. | 0 ->
  464. metapos, ""
  465. | _ ->
  466. metapos, read_cstring ctx i
  467. let read_sblob_idx ctx pos =
  468. let s = ctx.meta_stream in
  469. let metapos, i = if ctx.blob_offset = 2 then
  470. sread_ui16 s pos
  471. else
  472. sread_i32 s pos
  473. in
  474. match i with
  475. | 0 ->
  476. metapos,""
  477. | _ ->
  478. let bpos, len = read_compressed_i32 ctx.blob_stream i in
  479. metapos, String.sub ctx.blob_stream bpos len
  480. let read_sguid_idx ctx pos =
  481. let s = ctx.meta_stream in
  482. let metapos,i = if ctx.guid_offset = 2 then
  483. sread_ui16 s pos
  484. else
  485. sread_i32 s pos
  486. in
  487. match i with
  488. | 0 ->
  489. metapos, ""
  490. | _ ->
  491. let s = ctx.guid_stream in
  492. let i = i - 1 in
  493. let pos = i * 16 in
  494. metapos, String.sub s pos 16
  495. let read_callconv ctx s pos =
  496. let pos, conv = read_compressed_i32 s pos in
  497. let callconv = callconv_of_int conv ~match_generic_inst:true in
  498. let pos = match conv land 0x10 with
  499. | 0x10 -> fst (read_compressed_i32 s pos)
  500. | _ -> pos
  501. in
  502. pos, callconv
  503. let read_constant ctx with_type s pos =
  504. match with_type with
  505. | CBool ->
  506. pos+1, IBool (sget s (pos) <> 0)
  507. | CChar ->
  508. let pos, v = sread_ui16 s (pos) in
  509. pos, IChar v
  510. | CInt8 | CUInt8 ->
  511. pos+1,IByte (sget s (pos))
  512. | CInt16 | CUInt16 ->
  513. let pos, v = sread_ui16 s (pos) in
  514. pos, IShort v
  515. | CInt32 | CUInt32 ->
  516. let pos, v = sread_real_i32 s (pos) in
  517. pos, IInt v
  518. | CInt64 | CUInt64 ->
  519. let pos, v = sread_i64 s (pos) in
  520. pos, IInt64 v
  521. | CFloat32 ->
  522. let pos, v1 = sread_real_i32 s (pos) in
  523. pos, IFloat32 (Int32.float_of_bits v1)
  524. | CFloat64 ->
  525. let pos, v1 = sread_i64 s (pos) in
  526. pos, IFloat64 (Int64.float_of_bits v1)
  527. | CString ->
  528. if sget s pos = 0xff then
  529. pos+1,IString ""
  530. else
  531. let pos, len = read_compressed_i32 s pos in
  532. pos+len, IString (String.sub s pos len)
  533. | CNullRef ->
  534. pos+1, INull
  535. let sig_to_const = function
  536. | SBool -> CBool
  537. | SChar -> CChar
  538. | SInt8 -> CInt8
  539. | SUInt8 -> CUInt8
  540. | SInt16 -> CInt16
  541. | SUInt16 -> CUInt16
  542. | SInt32 -> CInt32
  543. | SUInt32 -> CUInt32
  544. | SInt64 -> CInt64
  545. | SUInt64 -> CUInt64
  546. | SFloat32 -> CFloat32
  547. | SFloat64 -> CFloat64
  548. | SString -> CString
  549. | _ -> CNullRef
  550. let read_constant_type ctx s pos = match sget s pos with
  551. | 0x2 -> pos+1, CBool (* 0x2 *)
  552. | 0x3 -> pos+1, CChar (* 0x3 *)
  553. | 0x4 -> pos+1, CInt8 (* 0x4 *)
  554. | 0x5 -> pos+1, CUInt8 (* 0x5 *)
  555. | 0x6 -> pos+1, CInt16 (* 0x6 *)
  556. | 0x7 -> pos+1, CUInt16 (* 0x7 *)
  557. | 0x8 -> pos+1, CInt32 (* 0x8 *)
  558. | 0x9 -> pos+1, CUInt32 (* 0x9 *)
  559. | 0xA -> pos+1, CInt64 (* 0xA *)
  560. | 0xB -> pos+1, CUInt64 (* 0xB *)
  561. | 0xC -> pos+1, CFloat32 (* 0xC *)
  562. | 0xD -> pos+1, CFloat64 (* 0xD *)
  563. | 0xE -> pos+1, CString (* 0xE *)
  564. | 0x12 -> pos+1, CNullRef (* 0x12 *)
  565. | i -> Printf.printf "0x%x\n" i; assert false
  566. let action_security_of_int = function
  567. | 0x1 -> SecRequest (* 0x1 *)
  568. | 0x2 -> SecDemand (* 0x2 *)
  569. | 0x3 -> SecAssert (* 0x3 *)
  570. | 0x4 -> SecDeny (* 0x4 *)
  571. | 0x5 -> SecPermitOnly (* 0x5 *)
  572. | 0x6 -> SecLinkCheck (* 0x6 *)
  573. | 0x7 -> SecInheritCheck (* 0x7 *)
  574. | 0x8 -> SecReqMin (* 0x8 *)
  575. | 0x9 -> SecReqOpt (* 0x9 *)
  576. | 0xA -> SecReqRefuse (* 0xA *)
  577. | 0xB -> SecPreJitGrant (* 0xB *)
  578. | 0xC -> SecPreJitDeny (* 0xC *)
  579. | 0xD -> SecNonCasDemand (* 0xD *)
  580. | 0xE -> SecNonCasLinkDemand (* 0xE *)
  581. | 0xF -> SecNonCasInheritance (* 0xF *)
  582. | _ -> assert false
  583. (* ******* Metadata Tables ********* *)
  584. let null_meta = UnknownMeta (-1)
  585. let mk_module id =
  586. {
  587. md_id = id;
  588. md_generation = 0;
  589. md_name = empty;
  590. md_vid = empty;
  591. md_encid = empty;
  592. md_encbase_id = empty;
  593. }
  594. let null_module = mk_module (-1)
  595. let mk_type_ref id =
  596. {
  597. tr_id = id;
  598. tr_resolution_scope = null_meta;
  599. tr_name = empty;
  600. tr_namespace = [];
  601. }
  602. let null_type_ref = mk_type_ref (-1)
  603. let mk_type_def id =
  604. {
  605. td_id = id;
  606. td_flags = null_type_def_flags;
  607. td_name = empty;
  608. td_namespace = [];
  609. td_extends = None;
  610. td_field_list = [];
  611. td_method_list = [];
  612. td_extra_enclosing = None;
  613. }
  614. let null_type_def = mk_type_def (-1)
  615. let mk_field id =
  616. {
  617. f_id = id;
  618. f_flags = null_field_flags;
  619. f_name = empty;
  620. f_signature = SVoid;
  621. }
  622. let null_field = mk_field (-1)
  623. let mk_field_ptr id =
  624. {
  625. fp_id = id;
  626. fp_field = null_field;
  627. }
  628. let null_field_ptr = mk_field_ptr (-1)
  629. let mk_method id =
  630. {
  631. m_id = id;
  632. m_rva = Int32.of_int (-1);
  633. m_flags = null_method_flags;
  634. m_name = empty;
  635. m_signature = SVoid;
  636. m_param_list = [];
  637. m_declaring = None;
  638. }
  639. let null_method = mk_method (-1)
  640. let mk_method_ptr id =
  641. {
  642. mp_id = id;
  643. mp_method = null_method;
  644. }
  645. let null_method_ptr = mk_method_ptr (-1)
  646. let mk_param id =
  647. {
  648. p_id = id;
  649. p_flags = null_param_flags;
  650. p_sequence = -1;
  651. p_name = empty;
  652. }
  653. let null_param = mk_param (-1)
  654. let mk_param_ptr id =
  655. {
  656. pp_id = id;
  657. pp_param = null_param;
  658. }
  659. let null_param_ptr = mk_param_ptr (-1)
  660. let mk_interface_impl id =
  661. {
  662. ii_id = id;
  663. ii_class = null_type_def; (* TypeDef rid *)
  664. ii_interface = null_meta;
  665. }
  666. let null_interface_impl = mk_interface_impl (-1)
  667. let mk_member_ref id =
  668. {
  669. memr_id = id;
  670. memr_class = null_meta;
  671. memr_name = empty;
  672. memr_signature = SVoid;
  673. }
  674. let null_member_ref = mk_member_ref (-1)
  675. let mk_constant id =
  676. {
  677. c_id = id;
  678. c_type = CNullRef;
  679. c_parent = null_meta;
  680. c_value = INull;
  681. }
  682. let null_constant = mk_constant (-1)
  683. let mk_custom_attribute id =
  684. {
  685. ca_id = id;
  686. ca_parent = null_meta;
  687. ca_type = null_meta;
  688. ca_value = None;
  689. }
  690. let null_custom_attribute = mk_custom_attribute (-1)
  691. let mk_field_marshal id =
  692. {
  693. fm_id = id;
  694. fm_parent = null_meta;
  695. fm_native_type = NVoid;
  696. }
  697. let null_field_marshal = mk_field_marshal (-1)
  698. let mk_decl_security id =
  699. {
  700. ds_id = id;
  701. ds_action = SecNull;
  702. ds_parent = null_meta;
  703. ds_permission_set = empty;
  704. }
  705. let mk_class_layout id =
  706. {
  707. cl_id = id;
  708. cl_packing_size = -1;
  709. cl_class_size = -1;
  710. cl_parent = null_type_def;
  711. }
  712. let mk_field_layout id =
  713. {
  714. fl_id = id;
  715. fl_offset = -1;
  716. fl_field = null_field;
  717. }
  718. let mk_stand_alone_sig id =
  719. {
  720. sa_id = id;
  721. sa_signature = SVoid;
  722. }
  723. let mk_event id =
  724. {
  725. e_id = id;
  726. e_flags = [];
  727. e_name = empty;
  728. e_event_type = null_meta;
  729. }
  730. let null_event = mk_event (-1)
  731. let mk_event_map id =
  732. {
  733. em_id = id;
  734. em_parent = null_type_def;
  735. em_event_list = [];
  736. }
  737. let mk_event_ptr id =
  738. {
  739. ep_id = id;
  740. ep_event = null_event;
  741. }
  742. let mk_property id =
  743. {
  744. prop_id = id;
  745. prop_flags = [];
  746. prop_name = empty;
  747. prop_type = SVoid;
  748. }
  749. let null_property = mk_property (-1)
  750. let mk_property_map id =
  751. {
  752. pm_id = id;
  753. pm_parent = null_type_def;
  754. pm_property_list = [];
  755. }
  756. let mk_property_ptr id =
  757. {
  758. prp_id = id;
  759. prp_property = null_property;
  760. }
  761. let mk_method_semantics id =
  762. {
  763. ms_id = id;
  764. ms_semantic = [];
  765. ms_method = null_method;
  766. ms_association = null_meta;
  767. }
  768. let mk_method_impl id =
  769. {
  770. mi_id = id;
  771. mi_class = null_type_def;
  772. mi_method_body = null_meta;
  773. mi_method_declaration = null_meta;
  774. }
  775. let mk_module_ref id =
  776. {
  777. modr_id = id;
  778. modr_name = empty;
  779. }
  780. let null_module_ref = mk_module_ref (-1)
  781. let mk_type_spec id =
  782. {
  783. ts_id = id;
  784. ts_signature = SVoid;
  785. }
  786. let mk_enc_log id =
  787. {
  788. el_id = id;
  789. el_token = -1;
  790. el_func_code = -1;
  791. }
  792. let mk_impl_map id =
  793. {
  794. im_id = id;
  795. im_flags = null_impl_flags;
  796. im_forwarded = null_meta;
  797. im_import_name = empty;
  798. im_import_scope = null_module_ref;
  799. }
  800. let mk_enc_map id =
  801. {
  802. encm_id = id;
  803. encm_token = -1;
  804. }
  805. let mk_field_rva id =
  806. {
  807. fr_id = id;
  808. fr_rva = Int32.zero;
  809. fr_field = null_field;
  810. }
  811. let mk_assembly id =
  812. {
  813. a_id = id;
  814. a_hash_algo = HNone;
  815. a_major = -1;
  816. a_minor = -1;
  817. a_build = -1;
  818. a_rev = -1;
  819. a_flags = [];
  820. a_public_key = empty;
  821. a_name = empty;
  822. a_locale = empty;
  823. }
  824. let mk_assembly_processor id =
  825. {
  826. ap_id = id;
  827. ap_processor = -1;
  828. }
  829. let mk_assembly_os id =
  830. {
  831. aos_id = id;
  832. aos_platform_id = -1;
  833. aos_major_version = -1;
  834. aos_minor_version = -1;
  835. }
  836. let mk_assembly_ref id =
  837. {
  838. ar_id = id;
  839. ar_major = -1;
  840. ar_minor = -1;
  841. ar_build = -1;
  842. ar_rev = -1;
  843. ar_flags = [];
  844. ar_public_key = empty;
  845. ar_name = empty;
  846. ar_locale = empty;
  847. ar_hash_value = empty;
  848. }
  849. let null_assembly_ref = mk_assembly_ref (-1)
  850. let mk_assembly_ref_processor id =
  851. {
  852. arp_id = id;
  853. arp_processor = -1;
  854. arp_assembly_ref = null_assembly_ref;
  855. }
  856. let mk_assembly_ref_os id =
  857. {
  858. aros_id = id;
  859. aros_platform_id = -1;
  860. aros_major = -1;
  861. aros_minor = -1;
  862. aros_assembly_ref = null_assembly_ref;
  863. }
  864. let mk_file id =
  865. {
  866. file_id = id;
  867. file_flags = ContainsMetadata;
  868. file_name = empty;
  869. file_hash_value = empty;
  870. }
  871. let mk_exported_type id =
  872. {
  873. et_id = id;
  874. et_flags = null_type_def_flags;
  875. et_type_def_id = -1;
  876. et_type_name = empty;
  877. et_type_namespace = [];
  878. et_implementation = null_meta;
  879. }
  880. let mk_manifest_resource id =
  881. {
  882. mr_id = id;
  883. mr_offset = -1;
  884. mr_flags = RNone;
  885. mr_name = empty;
  886. mr_implementation = None;
  887. }
  888. let mk_nested_class id =
  889. {
  890. nc_id = id;
  891. nc_nested = null_type_def;
  892. nc_enclosing = null_type_def;
  893. }
  894. let mk_generic_param id =
  895. {
  896. gp_id = id;
  897. gp_number = -1;
  898. gp_flags = null_generic_flags;
  899. gp_owner = null_meta;
  900. gp_name = None;
  901. }
  902. let null_generic_param = mk_generic_param (-1)
  903. let mk_method_spec id =
  904. {
  905. mspec_id = id;
  906. mspec_method = null_meta;
  907. mspec_instantiation = SVoid;
  908. }
  909. let mk_generic_param_constraint id =
  910. {
  911. gc_id = id;
  912. gc_owner = null_generic_param;
  913. gc_constraint = null_meta;
  914. }
  915. let mk_meta tbl id = match tbl with
  916. | IModule -> Module (mk_module id)
  917. | ITypeRef -> TypeRef (mk_type_ref id)
  918. | ITypeDef -> TypeDef (mk_type_def id)
  919. | IFieldPtr -> FieldPtr (mk_field_ptr id)
  920. | IField -> Field (mk_field id)
  921. | IMethodPtr -> MethodPtr (mk_method_ptr id)
  922. | IMethod -> Method (mk_method id)
  923. | IParamPtr -> ParamPtr (mk_param_ptr id)
  924. | IParam -> Param (mk_param id)
  925. | IInterfaceImpl -> InterfaceImpl (mk_interface_impl id)
  926. | IMemberRef -> MemberRef (mk_member_ref id)
  927. | IConstant -> Constant (mk_constant id)
  928. | ICustomAttribute -> CustomAttribute (mk_custom_attribute id)
  929. | IFieldMarshal -> FieldMarshal(mk_field_marshal id)
  930. | IDeclSecurity -> DeclSecurity(mk_decl_security id)
  931. | IClassLayout -> ClassLayout(mk_class_layout id)
  932. | IFieldLayout -> FieldLayout(mk_field_layout id)
  933. | IStandAloneSig -> StandAloneSig(mk_stand_alone_sig id)
  934. | IEventMap -> EventMap(mk_event_map id)
  935. | IEventPtr -> EventPtr(mk_event_ptr id)
  936. | IEvent -> Event(mk_event id)
  937. | IPropertyMap -> PropertyMap(mk_property_map id)
  938. | IPropertyPtr -> PropertyPtr(mk_property_ptr id)
  939. | IProperty -> Property(mk_property id)
  940. | IMethodSemantics -> MethodSemantics(mk_method_semantics id)
  941. | IMethodImpl -> MethodImpl(mk_method_impl id)
  942. | IModuleRef -> ModuleRef(mk_module_ref id)
  943. | ITypeSpec -> TypeSpec(mk_type_spec id)
  944. | IImplMap -> ImplMap(mk_impl_map id)
  945. | IFieldRVA -> FieldRVA(mk_field_rva id)
  946. | IENCLog -> ENCLog(mk_enc_log id)
  947. | IENCMap -> ENCMap(mk_enc_map id)
  948. | IAssembly -> Assembly(mk_assembly id)
  949. | IAssemblyProcessor -> AssemblyProcessor(mk_assembly_processor id)
  950. | IAssemblyOS -> AssemblyOS(mk_assembly_os id)
  951. | IAssemblyRef -> AssemblyRef(mk_assembly_ref id)
  952. | IAssemblyRefProcessor -> AssemblyRefProcessor(mk_assembly_ref_processor id)
  953. | IAssemblyRefOS -> AssemblyRefOS(mk_assembly_ref_os id)
  954. | IFile -> File(mk_file id)
  955. | IExportedType -> ExportedType(mk_exported_type id)
  956. | IManifestResource -> ManifestResource(mk_manifest_resource id)
  957. | INestedClass -> NestedClass(mk_nested_class id)
  958. | IGenericParam -> GenericParam(mk_generic_param id)
  959. | IMethodSpec -> MethodSpec(mk_method_spec id)
  960. | IGenericParamConstraint -> GenericParamConstraint(mk_generic_param_constraint id)
  961. | i -> UnknownMeta (int_of_table i)
  962. let get_table ctx idx rid =
  963. let cur = ctx.tables.(int_of_table idx) in
  964. DynArray.get cur (rid-1)
  965. (* special coded types *)
  966. let max_clr_meta_idx = 76
  967. let coded_description = Array.init (max_clr_meta_idx - 63) (fun i ->
  968. let i = 64 + i in
  969. match table_of_int i with
  970. | ITypeDefOrRef ->
  971. Array.of_list [ITypeDef;ITypeRef;ITypeSpec], 2
  972. | IHasConstant ->
  973. Array.of_list [IField;IParam;IProperty], 2
  974. | IHasCustomAttribute ->
  975. Array.of_list
  976. [IMethod;IField;ITypeRef;ITypeDef;IParam;IInterfaceImpl;IMemberRef;
  977. IModule;IDeclSecurity;IProperty;IEvent;IStandAloneSig;IModuleRef;
  978. ITypeSpec;IAssembly;IAssemblyRef;IFile;IExportedType;IManifestResource;
  979. IGenericParam;IGenericParamConstraint;IMethodSpec], 5
  980. | IHasFieldMarshal ->
  981. Array.of_list [IField;IParam], 1
  982. | IHasDeclSecurity ->
  983. Array.of_list [ITypeDef;IMethod;IAssembly], 2
  984. | IMemberRefParent ->
  985. Array.of_list [ITypeDef;ITypeRef;IModuleRef;IMethod;ITypeSpec], 3
  986. | IHasSemantics ->
  987. Array.of_list [IEvent;IProperty], 1
  988. | IMethodDefOrRef ->
  989. Array.of_list [IMethod;IMemberRef], 1
  990. | IMemberForwarded ->
  991. Array.of_list [IField;IMethod], 1
  992. | IImplementation ->
  993. Array.of_list [IFile;IAssemblyRef;IExportedType], 2
  994. | ICustomAttributeType ->
  995. Array.of_list [ITypeRef(* unused ? *);ITypeDef (* unused ? *);IMethod;IMemberRef(*;IString FIXME *)], 3
  996. | IResolutionScope ->
  997. Array.of_list [IModule;IModuleRef;IAssemblyRef;ITypeRef], 2
  998. | ITypeOrMethodDef ->
  999. Array.of_list [ITypeDef;IMethod], 1
  1000. | _ ->
  1001. print_endline ("Unknown coded index: " ^ string_of_int i);
  1002. assert false)
  1003. let set_coded_sizes ctx rows =
  1004. let check i tbls max =
  1005. if List.exists (fun t ->
  1006. let _, nrows = rows.(int_of_table t) in
  1007. nrows >= max
  1008. ) tbls then
  1009. ctx.table_sizes.(i) <- sread_i32
  1010. in
  1011. for i = 64 to (max_clr_meta_idx) do
  1012. let tbls, size = coded_description.(i - 64) in
  1013. let max = 1 lsl (16 - size) in
  1014. check i (Array.to_list tbls) max
  1015. done
  1016. let sread_from_table_opt ctx in_blob tbl s pos =
  1017. let i = int_of_table tbl in
  1018. let sread = if in_blob then
  1019. read_compressed_i32
  1020. else
  1021. ctx.table_sizes.(i)
  1022. in
  1023. let pos, rid = sread s pos in
  1024. if i >= 64 then begin
  1025. let tbls,size = coded_description.(i-64) in
  1026. let mask = (1 lsl size) - 1 in
  1027. let mask = if mask = 0 then 1 else mask in
  1028. let tidx = rid land mask in
  1029. let real_rid = rid lsr size in
  1030. let real_tbl = tbls.(tidx) in
  1031. (* printf "rid 0x%x - table idx 0x%x - real_rid 0x%x\n\n" rid tidx real_rid; *)
  1032. if real_rid = 0 then
  1033. pos, None
  1034. else
  1035. pos, Some (get_table ctx real_tbl real_rid)
  1036. end else if rid = 0 then
  1037. pos, None
  1038. else
  1039. pos, Some (get_table ctx tbl rid)
  1040. let sread_from_table ctx in_blob tbl s pos =
  1041. let pos, opt = sread_from_table_opt ctx in_blob tbl s pos in
  1042. pos, Option.get opt
  1043. (* ******* SIGNATURE READING ********* *)
  1044. let read_inline_str s pos =
  1045. let pos, len = read_compressed_i32 s pos in
  1046. let ret = String.sub s pos len in
  1047. pos+len,ret
  1048. let rec read_ilsig ctx s pos =
  1049. let i = sget s pos in
  1050. (* printf "0x%x\n" i; *)
  1051. let pos = pos + 1 in
  1052. match i with
  1053. | 0x1 -> pos, SVoid (* 0x1 *)
  1054. | 0x2 -> pos, SBool (* 0x2 *)
  1055. | 0x3 -> pos, SChar (* 0x3 *)
  1056. | 0x4 -> pos, SInt8 (* 0x4 *)
  1057. | 0x5 -> pos, SUInt8 (* 0x5 *)
  1058. | 0x6 -> pos, SInt16 (* 0x6 *)
  1059. | 0x7 -> pos, SUInt16 (* 0x7 *)
  1060. | 0x8 -> pos, SInt32 (* 0x8 *)
  1061. | 0x9 -> pos, SUInt32 (* 0x9 *)
  1062. | 0xA -> pos, SInt64 (* 0xA *)
  1063. | 0xB -> pos, SUInt64 (* 0xB *)
  1064. | 0xC -> pos, SFloat32 (* 0xC *)
  1065. | 0xD -> pos, SFloat64 (* 0xD *)
  1066. | 0xE -> pos, SString (* 0xE *)
  1067. | 0xF ->
  1068. let pos, s = read_ilsig ctx s pos in
  1069. pos, SPointer s
  1070. | 0x10 ->
  1071. let pos, s = read_ilsig ctx s pos in
  1072. pos, SManagedPointer s
  1073. | 0x11 ->
  1074. let pos, vt = sread_from_table ctx true ITypeDefOrRef s pos in
  1075. pos, SValueType vt
  1076. | 0x12 ->
  1077. let pos, c = sread_from_table ctx true ITypeDefOrRef s pos in
  1078. pos, SClass c
  1079. | 0x13 ->
  1080. let n = sget s pos in
  1081. pos + 1, STypeParam n
  1082. | 0x14 ->
  1083. let pos, ssig = read_ilsig ctx s pos in
  1084. let pos, rank = read_compressed_i32 s pos in
  1085. let pos, numsizes = read_compressed_i32 s pos in
  1086. let pos = ref pos in
  1087. let sizearray = Array.init numsizes (fun _ ->
  1088. let p, size = read_compressed_i32 s !pos in
  1089. pos := p;
  1090. size
  1091. ) in
  1092. let pos, bounds = read_compressed_i32 s !pos in
  1093. let pos = ref pos in
  1094. let boundsarray = Array.init bounds (fun _ ->
  1095. let p, b = read_compressed_i32 s !pos in
  1096. pos := p;
  1097. let signed = b land 0x1 = 0x1 in
  1098. let b = b lsr 1 in
  1099. if signed then -b else b
  1100. ) in
  1101. let ret = Array.init rank (fun i ->
  1102. (if i >= bounds then None else Some boundsarray.(i))
  1103. , (if i >= numsizes then None else Some sizearray.(i))
  1104. ) in
  1105. !pos, SArray(ssig, ret)
  1106. | 0x15 ->
  1107. (* let pos, c = sread_from_table ctx ITypeDefOrRef s pos in *)
  1108. let pos, ssig = read_ilsig ctx s pos in
  1109. let pos, ntypes = read_compressed_i32 s pos in
  1110. let rec loop acc pos n =
  1111. if n > ntypes then
  1112. pos, List.rev acc
  1113. else
  1114. let pos, ssig = read_ilsig ctx s pos in
  1115. loop (ssig :: acc) pos (n+1)
  1116. in
  1117. let pos, args = loop [] pos 1 in
  1118. pos, SGenericInst (ssig, args)
  1119. | 0x16 -> pos, STypedReference (* 0x16 *)
  1120. | 0x18 -> pos, SIntPtr (* 0x18 *)
  1121. | 0x19 -> pos, SUIntPtr (* 0x19 *)
  1122. | 0x1B ->
  1123. let pos, conv = read_compressed_i32 s pos in
  1124. let callconv = callconv_of_int conv in
  1125. let pos, ntypes = read_compressed_i32 s pos in
  1126. let pos, ret = read_ilsig ctx s pos in
  1127. let rec loop acc pos n =
  1128. if n >= ntypes then
  1129. pos, List.rev acc
  1130. else
  1131. let pos, ssig = read_ilsig ctx s pos in
  1132. loop (ssig :: acc) pos (n+1)
  1133. in
  1134. let pos, args = loop [] pos 1 in
  1135. pos, SFunPtr (callconv, ret, args)
  1136. | 0x1C -> pos, SObject (* 0x1C *)
  1137. | 0x1D ->
  1138. let pos, ssig = read_ilsig ctx s pos in
  1139. pos, SVector ssig
  1140. | 0x1E ->
  1141. let pos, conv = read_compressed_i32 s pos in
  1142. pos, SMethodTypeParam conv
  1143. | 0x1F ->
  1144. let pos, tdef = sread_from_table ctx true ITypeDefOrRef s pos in
  1145. let pos, ilsig = read_ilsig ctx s pos in
  1146. pos, SReqModifier (tdef, ilsig)
  1147. | 0x20 ->
  1148. let pos, tdef = sread_from_table ctx true ITypeDefOrRef s pos in
  1149. let pos, ilsig = read_ilsig ctx s pos in
  1150. pos, SOptModifier (tdef, ilsig)
  1151. | 0x41 -> pos, SSentinel (* 0x41 *)
  1152. | 0x45 ->
  1153. let pos, ssig = read_ilsig ctx s pos in
  1154. pos,SPinned ssig (* 0x45 *)
  1155. (* special undocumented constants *)
  1156. | 0x50 -> pos, SType
  1157. | 0x51 -> pos, SBoxed
  1158. | 0x55 ->
  1159. let pos, vt = read_inline_str s pos in
  1160. pos, SEnum vt
  1161. | _ ->
  1162. Printf.printf "unknown ilsig 0x%x\n\n" i;
  1163. assert false
  1164. let rec read_variantsig ctx s pos =
  1165. let pos, b = sread_ui8 s pos in
  1166. match b with
  1167. | 0x00 -> pos, VT_EMPTY (* 0x00 *)
  1168. | 0x01 -> pos, VT_NULL (* 0x01 *)
  1169. | 0x02 -> pos, VT_I2 (* 0x02 *)
  1170. | 0x03 -> pos, VT_I4 (* 0x03 *)
  1171. | 0x04 -> pos, VT_R4 (* 0x04 *)
  1172. | 0x05 -> pos, VT_R8 (* 0x05 *)
  1173. | 0x06 -> pos, VT_CY (* 0x06 *)
  1174. | 0x07 -> pos, VT_DATE (* 0x07 *)
  1175. | 0x08 -> pos, VT_BSTR (* 0x08 *)
  1176. | 0x09 -> pos, VT_DISPATCH (* 0x09 *)
  1177. | 0x0A -> pos, VT_ERROR (* 0x0A *)
  1178. | 0x0B -> pos, VT_BOOL (* 0x0B *)
  1179. | 0x0C -> pos, VT_VARIANT (* 0x0C *)
  1180. | 0x0D -> pos, VT_UNKNOWN (* 0x0D *)
  1181. | 0x0E -> pos, VT_DECIMAL (* 0x0E *)
  1182. | 0x10 -> pos, VT_I1 (* 0x10 *)
  1183. | 0x11 -> pos, VT_UI1 (* 0x11 *)
  1184. | 0x12 -> pos, VT_UI2 (* 0x12 *)
  1185. | 0x13 -> pos, VT_UI4 (* 0x13 *)
  1186. | 0x14 -> pos, VT_I8 (* 0x14 *)
  1187. | 0x15 -> pos, VT_UI8 (* 0x15 *)
  1188. | 0x16 -> pos, VT_INT (* 0x16 *)
  1189. | 0x17 -> pos, VT_UINT (* 0x17 *)
  1190. | 0x18 -> pos, VT_VOID (* 0x18 *)
  1191. | 0x19 -> pos, VT_HRESULT (* 0x19 *)
  1192. | 0x1A -> pos, VT_PTR (* 0x1A *)
  1193. | 0x1B -> pos, VT_SAFEARRAY (* 0x1B *)
  1194. | 0x1C -> pos, VT_CARRAY (* 0x1C *)
  1195. | 0x1D -> pos, VT_USERDEFINED (* 0x1D *)
  1196. | 0x1E -> pos, VT_LPSTR (* 0x1E *)
  1197. | 0x1F -> pos, VT_LPWSTR (* 0x1F *)
  1198. | 0x24 -> pos, VT_RECORD (* 0x24 *)
  1199. | 0x40 -> pos, VT_FILETIME (* 0x40 *)
  1200. | 0x41 -> pos, VT_BLOB (* 0x41 *)
  1201. | 0x42 -> pos, VT_STREAM (* 0x42 *)
  1202. | 0x43 -> pos, VT_STORAGE (* 0x43 *)
  1203. | 0x44 -> pos, VT_STREAMED_OBJECT (* 0x44 *)
  1204. | 0x45 -> pos, VT_STORED_OBJECT (* 0x45 *)
  1205. | 0x46 -> pos, VT_BLOB_OBJECT (* 0x46 *)
  1206. | 0x47 -> pos, VT_CF (* 0x47 *)
  1207. | 0x48 -> pos, VT_CLSID (* 0x48 *)
  1208. | _ -> assert false
  1209. let rec read_nativesig ctx s pos : int * nativesig =
  1210. let pos, b = sread_ui8 s pos in
  1211. match b with
  1212. | 0x01 -> pos, NVoid (* 0x01 *)
  1213. | 0x02 -> pos, NBool (* 0x02 *)
  1214. | 0x03 -> pos, NInt8 (* 0x03 *)
  1215. | 0x4 -> pos, NUInt8 (* 0x4 *)
  1216. | 0x5 -> pos, NInt16 (* 0x5 *)
  1217. | 0x6 -> pos, NUInt16 (* 0x6 *)
  1218. | 0x7 -> pos, NInt32 (* 0x7 *)
  1219. | 0x8 -> pos, NUInt32 (* 0x8 *)
  1220. | 0x9 -> pos, NInt64 (* 0x9 *)
  1221. | 0xA -> pos, NUInt64 (* 0xA *)
  1222. | 0xB -> pos, NFloat32 (* 0xB *)
  1223. | 0xC -> pos, NFloat64 (* 0xC *)
  1224. | 0xD -> pos, NSysChar (* 0xD *)
  1225. | 0xE -> pos, NVariant (* 0xE *)
  1226. | 0xF -> pos, NCurrency (* 0xF *)
  1227. | 0x10 -> pos, NPointer (* 0x10 *)
  1228. | 0x11 -> pos, NDecimal (* 0x11 *)
  1229. | 0x12 -> pos, NDate (* 0x12 *)
  1230. | 0x13 -> pos, NBStr (* 0x13 *)
  1231. | 0x14 -> pos, NLPStr (* 0x14 *)
  1232. | 0x15 -> pos, NLPWStr (* 0x15 *)
  1233. | 0x16 -> pos, NLPTStr (* 0x16 *)
  1234. | 0x17 ->
  1235. let pos, size = read_compressed_i32 s pos in
  1236. pos, NFixedString size
  1237. | 0x18 -> pos, NObjectRef (* 0x18 *)
  1238. | 0x19 -> pos, NUnknown (* 0x19 *)
  1239. | 0x1A -> pos, NDispatch (* 0x1A *)
  1240. | 0x1B -> pos, NStruct (* 0x1B *)
  1241. | 0x1C -> pos, NInterface (* 0x1C *)
  1242. | 0x1D ->
  1243. let pos, v = read_variantsig ctx s pos in
  1244. pos, NSafeArray v
  1245. | 0x1E ->
  1246. let pos, size = read_compressed_i32 s pos in
  1247. let pos, t = read_variantsig ctx s pos in
  1248. pos, NFixedArray (size,t)
  1249. | 0x1F -> pos, NIntPointer (* 0x1F *)
  1250. | 0x20 -> pos, NUIntPointer (* 0x20 *)
  1251. | 0x21 -> pos, NNestedStruct (* 0x21 *)
  1252. | 0x22 -> pos, NByValStr (* 0x22 *)
  1253. | 0x23 -> pos, NAnsiBStr (* 0x23 *)
  1254. | 0x24 -> pos, NTBStr (* 0x24 *)
  1255. | 0x25 -> pos, NVariantBool (* 0x25 *)
  1256. | 0x26 -> pos, NFunctionPtr (* 0x26 *)
  1257. | 0x28 -> pos, NAsAny (* 0x28 *)
  1258. | 0x2A ->
  1259. let pos, elt = read_nativesig ctx s pos in
  1260. let pos, paramidx = read_compressed_i32 s pos in
  1261. let pos, size = read_compressed_i32 s pos in
  1262. let pos, param_mult = read_compressed_i32 s pos in
  1263. pos, NArray(elt,paramidx,size,param_mult)
  1264. | 0x2B -> pos, NLPStruct (* 0x2B *)
  1265. | 0x2C ->
  1266. let pos, guid_val = read_inline_str s pos in
  1267. let pos, unmanaged = read_inline_str s pos in
  1268. (* FIXME: read TypeRef *)
  1269. pos, NCustomMarshaler (guid_val,unmanaged)
  1270. | 0x2D -> pos, NError (* 0x2D *)
  1271. | i -> pos, NCustom i
  1272. let read_blob_idx ctx s pos =
  1273. let metapos,i = if ctx.blob_offset = 2 then
  1274. sread_ui16 s pos
  1275. else
  1276. sread_i32 s pos
  1277. in
  1278. metapos, i
  1279. let read_nativesig_idx ctx s pos =
  1280. let s = ctx.meta_stream in
  1281. let metapos,i = if ctx.blob_offset = 2 then
  1282. sread_ui16 s pos
  1283. else
  1284. sread_i32 s pos
  1285. in
  1286. let s = ctx.blob_stream in
  1287. let _, ret = read_nativesig ctx s i in
  1288. metapos, ret
  1289. let read_method_ilsig_idx ctx pos =
  1290. let s = ctx.meta_stream in
  1291. let metapos,i = if ctx.blob_offset = 2 then
  1292. sread_ui16 s pos
  1293. else
  1294. sread_i32 s pos
  1295. in
  1296. let s = ctx.blob_stream in
  1297. let pos, len = read_compressed_i32 s i in
  1298. (* for x = 0 to len do *)
  1299. (* printf "%x " (sget s (i+x)) *)
  1300. (* done; *)
  1301. let endpos = pos + len in
  1302. (* printf "\n"; *)
  1303. let pos, callconv = read_callconv ctx s pos in
  1304. let pos, ntypes = read_compressed_i32 s pos in
  1305. let pos, ret = read_ilsig ctx s pos in
  1306. let rec loop acc pos n =
  1307. if n > ntypes || pos >= endpos then
  1308. pos, List.rev acc
  1309. else
  1310. let pos, ssig = read_ilsig ctx s pos in
  1311. loop (ssig :: acc) pos (n+1)
  1312. in
  1313. let pos, args = loop [] pos 1 in
  1314. metapos, SFunPtr (callconv, ret, args)
  1315. let read_ilsig_idx ctx pos =
  1316. let s = ctx.meta_stream in
  1317. let metapos,i = if ctx.blob_offset = 2 then
  1318. sread_ui16 s pos
  1319. else
  1320. sread_i32 s pos
  1321. in
  1322. let s = ctx.blob_stream in
  1323. let i, _ = read_compressed_i32 s i in
  1324. let _, ilsig = read_ilsig ctx s i in
  1325. metapos, ilsig
  1326. let read_field_ilsig_idx ?(force_field=true) ctx pos =
  1327. let s = ctx.meta_stream in
  1328. let metapos,i = if ctx.blob_offset = 2 then
  1329. sread_ui16 s pos
  1330. else
  1331. sread_i32 s pos
  1332. in
  1333. let s = ctx.blob_stream in
  1334. let i, _ = read_compressed_i32 s i in
  1335. if sget s i <> 0x6 then
  1336. if force_field then
  1337. error ("Invalid field signature: " ^ string_of_int (sget s i))
  1338. else
  1339. read_method_ilsig_idx ctx pos
  1340. else
  1341. let _, ilsig = read_ilsig ctx s (i+1) in
  1342. metapos, ilsig
  1343. let get_underlying_enum_type ctx name =
  1344. (* first try to get a typedef *)
  1345. let ns, name = match List.rev (String.nsplit name ".") with
  1346. | name :: ns -> List.rev ns, name
  1347. | _ -> assert false
  1348. in
  1349. try
  1350. let tdefs = ctx.tables.(int_of_table ITypeDef) in
  1351. let len = DynArray.length tdefs in
  1352. let rec loop_find idx =
  1353. if idx >= len then
  1354. raise Not_found
  1355. else
  1356. let tdef = match DynArray.get tdefs idx with | TypeDef td -> td | _ -> assert false in
  1357. if tdef.td_name = name && tdef.td_namespace = ns then
  1358. tdef
  1359. else
  1360. loop_find (idx+1)
  1361. in
  1362. let tdef = loop_find 1 in
  1363. (* now find the first static field associated with it *)
  1364. try
  1365. let nonstatic = List.find (fun f ->
  1366. not (List.mem CStatic f.f_flags.ff_contract)
  1367. ) tdef.td_field_list in
  1368. nonstatic.f_signature
  1369. with | Not_found -> assert false (* should never happen! *)
  1370. with | Not_found ->
  1371. (* FIXME: in order to correctly handle SEnum, we need to look it up *)
  1372. (* from either this assembly or from any other assembly that we reference *)
  1373. (* this is tricky - specially since this reader does not intend to handle file system *)
  1374. (* operations by itself. For now, if an enum is referenced from another module, *)
  1375. (* we won't handle it. The `cache` structure is laid out to deal with these problems *)
  1376. (* but isn't implemented yet *)
  1377. raise Exit
  1378. let read_custom_attr ctx attr_type s pos =
  1379. let pos, prolog = sread_ui16 s pos in
  1380. if prolog <> 0x0001 then error (sprintf "Error reading custom attribute: Expected prolog 0x0001 ; got 0x%x" prolog);
  1381. let isig = match attr_type with
  1382. | Method m -> m.m_signature
  1383. | MemberRef mr -> mr.memr_signature
  1384. | _ -> assert false
  1385. in
  1386. let args = match follow isig with
  1387. | SFunPtr (_,ret,args) -> args
  1388. | _ -> assert false
  1389. in
  1390. let rec read_instance ilsig pos =
  1391. (* print_endline (IlMetaDebug.ilsig_s ilsig); *)
  1392. match follow ilsig with
  1393. | SBool | SChar | SInt8 | SUInt8 | SInt16 | SUInt16
  1394. | SInt32 | SUInt32 | SInt64 | SUInt64 | SFloat32 | SFloat64 | SString ->
  1395. let pos, cons = read_constant ctx (sig_to_const ilsig) s pos in
  1396. pos, InstConstant (cons)
  1397. | SClass c when is_type (["System"],"Type") c ->
  1398. if (sget s pos) == 0xff then
  1399. pos+1, InstConstant INull
  1400. else
  1401. let pos, len = read_compressed_i32 s pos in
  1402. pos+len, InstType (String.sub s pos len)
  1403. | SType ->
  1404. let pos, len = read_compressed_i32 s pos in
  1405. pos+len, InstType (String.sub s pos len)
  1406. | SObject | SBoxed -> (* boxed *)
  1407. let pos = if sget s pos = 0x51 then pos+1 else pos in
  1408. let pos, ilsig = read_ilsig ctx s pos in
  1409. let pos, ret = read_instance ilsig pos in
  1410. pos, InstBoxed( ret )
  1411. (* (match follow ilsig with *)
  1412. (* | SEnum e -> *)
  1413. (* let ilsig = get_underlying_enum_type ctx e; *)
  1414. (* let pos,e = if is_boxed then sread_i32 s pos else read_compressed_i32 s pos in *)
  1415. (* pos, InstBoxed(InstEnum e) *)
  1416. (* | _ -> *)
  1417. (* let pos, boxed = read_constant ctx (sig_to_const ilsig) s pos in *)
  1418. (* pos, InstBoxed (InstConstant boxed)) *)
  1419. | SEnum e ->
  1420. let ilsig = get_underlying_enum_type ctx e in
  1421. read_instance ilsig pos
  1422. | SValueType _ -> (* enum *)
  1423. let pos, e = sread_i32 s pos in
  1424. pos, InstEnum e
  1425. | _ -> assert false
  1426. in
  1427. let rec read_fixed acc args pos = match args with
  1428. | [] ->
  1429. pos, List.rev acc
  1430. | SVector isig :: args ->
  1431. (* print_endline "vec"; *)
  1432. let pos, nelem = sread_real_i32 s pos in
  1433. let pos, ret = if nelem = -1l then
  1434. pos, InstConstant INull
  1435. else
  1436. let nelem = Int32.to_int nelem in
  1437. let rec loop acc pos n =
  1438. if n = nelem then
  1439. pos, InstArray (List.rev acc)
  1440. else
  1441. let pos, inst = read_instance isig pos in
  1442. loop (inst :: acc) pos (n+1)
  1443. in
  1444. loop [] pos 0
  1445. in
  1446. read_fixed (ret :: acc) args pos
  1447. | isig :: args ->
  1448. let pos, i = read_instance isig pos in
  1449. read_fixed (i :: acc) args pos
  1450. in
  1451. (* let tpos = pos in *)
  1452. let pos, fixed = read_fixed [] args pos in
  1453. (* printf "fixed %d : " (List.length args); *)
  1454. (* for x = tpos to pos do *)
  1455. (* printf "%x " (sget s x) *)
  1456. (* done; *)
  1457. (* printf "\n"; *)
  1458. (* let len = String.length s - pos - 1 in *)
  1459. (* let len = if len > 10 then 10 else len in *)
  1460. (* for x = 0 to len do *)
  1461. (* printf "%x " (sget s (pos + x)) *)
  1462. (* done; *)
  1463. (* printf "\n"; *)
  1464. let pos, nnamed = read_compressed_i32 s pos in
  1465. let pos = if nnamed > 0 then pos+1 else pos in
  1466. (* FIXME: this is a hack / quick fix around #3485 . We need to actually read named arguments *)
  1467. (* let rec read_named acc pos n = *)
  1468. (* if n = nnamed then *)
  1469. (* pos, List.rev acc *)
  1470. (* else *)
  1471. (* let pos, forp = sread_ui8 s pos in *)
  1472. (* let is_prop = if forp = 0x53 then *)
  1473. (* false *)
  1474. (* else if forp = 0x54 then *)
  1475. (* true *)
  1476. (* else *)
  1477. (* error (sprintf "named custom attribute error: expected 0x53 or 0x54 - got 0x%x" forp) *)
  1478. (* in *)
  1479. (* let pos, t = read_ilsig ctx s pos in *)
  1480. (* let pos, len = read_compressed_i32 s pos in *)
  1481. (* let name = String.sub s pos len in *)
  1482. (* let pos = pos+len in *)
  1483. (* let pos, inst = read_instance t pos in *)
  1484. (* read_named ( (is_prop, name, inst) :: acc ) pos (n+1) *)
  1485. (* in *)
  1486. (* let pos, named = read_named [] pos 0 in *)
  1487. pos, (fixed, [])
  1488. (* pos, (fixed, named) *)
  1489. let read_custom_attr_idx ctx ca attr_type pos =
  1490. let s = ctx.meta_stream in
  1491. let metapos,i = if ctx.blob_offset = 2 then
  1492. sread_ui16 s pos
  1493. else
  1494. sread_i32 s pos
  1495. in
  1496. if i = 0 then
  1497. metapos
  1498. else
  1499. let s = ctx.blob_stream in
  1500. let i, _ = read_compressed_i32 s i in
  1501. ctx.delays <- (fun () ->
  1502. try
  1503. let _, attr = read_custom_attr ctx attr_type s i in
  1504. ca.ca_value <- Some attr
  1505. with | Exit ->
  1506. ()
  1507. ) :: ctx.delays;
  1508. metapos
  1509. let read_next_index ctx offset table last pos =
  1510. if last then
  1511. DynArray.length ctx.tables.(int_of_table table) + 1
  1512. else
  1513. let s = ctx.meta_stream in
  1514. let _, idx = ctx.table_sizes.(int_of_table table) s (pos+offset) in
  1515. idx
  1516. let get_rev_list ctx table ptr_table begin_idx end_idx =
  1517. (* first check if index exists on pointer table *)
  1518. let ptr_table_t = ctx.tables.(int_of_table ptr_table) in
  1519. (* printf "table %d begin %d end %d\n" (int_of_table table) begin_idx end_idx; *)
  1520. match ctx.compressed, DynArray.length ptr_table_t with
  1521. | true, _ | _, 0 ->
  1522. (* use direct index *)
  1523. let rec loop idx acc =
  1524. if idx >= end_idx then
  1525. acc
  1526. else
  1527. loop (idx+1) (get_table ctx table idx :: acc)
  1528. in
  1529. loop begin_idx []
  1530. | _ ->
  1531. (* use indirect index *)
  1532. let rec loop idx acc =
  1533. if idx > end_idx then
  1534. acc
  1535. else
  1536. loop (idx+1) (get_table ctx ptr_table idx :: acc)
  1537. in
  1538. let ret = loop begin_idx [] in
  1539. List.map (fun meta ->
  1540. let p = meta_root_ptr meta in
  1541. get_table ctx table p.ptr_to.root_id
  1542. ) ret
  1543. let read_list ctx table ptr_table begin_idx offset last pos =
  1544. let end_idx = read_next_index ctx offset table last pos in
  1545. get_rev_list ctx table ptr_table begin_idx end_idx
  1546. let parse_ns id = match String.nsplit id "." with
  1547. | [""] -> []
  1548. | ns -> ns
  1549. let get_meta_pointer = function
  1550. | Module r -> IModule, r.md_id
  1551. | TypeRef r -> ITypeRef, r.tr_id
  1552. | TypeDef r -> ITypeDef, r.td_id
  1553. | FieldPtr r -> IFieldPtr, r.fp_id
  1554. | Field r -> IField, r.f_id
  1555. | MethodPtr r -> IMethodPtr, r.mp_id
  1556. | Method r -> IMethod, r.m_id
  1557. | ParamPtr r -> IParamPtr, r.pp_id
  1558. | Param r -> IParam, r.p_id
  1559. | InterfaceImpl r -> IInterfaceImpl, r.ii_id
  1560. | MemberRef r -> IMemberRef, r.memr_id
  1561. | Constant r -> IConstant, r.c_id
  1562. | CustomAttribute r -> ICustomAttribute, r.ca_id
  1563. | FieldMarshal r -> IFieldMarshal, r.fm_id
  1564. | DeclSecurity r -> IDeclSecurity, r.ds_id
  1565. | ClassLayout r -> IClassLayout, r.cl_id
  1566. | FieldLayout r -> IFieldLayout, r.fl_id
  1567. | StandAloneSig r -> IStandAloneSig, r.sa_id
  1568. | EventMap r -> IEventMap, r.em_id
  1569. | EventPtr r -> IEventPtr, r.ep_id
  1570. | Event r -> IEvent, r.e_id
  1571. | PropertyMap r -> IPropertyMap, r.pm_id
  1572. | PropertyPtr r -> IPropertyPtr, r.prp_id
  1573. | Property r -> IProperty, r.prop_id
  1574. | MethodSemantics r -> IMethodSemantics, r.ms_id
  1575. | MethodImpl r -> IMethodImpl, r.mi_id
  1576. | ModuleRef r -> IModuleRef, r.modr_id
  1577. | TypeSpec r -> ITypeSpec, r.ts_id
  1578. | ImplMap r -> IImplMap, r.im_id
  1579. | FieldRVA r -> IFieldRVA, r.fr_id
  1580. | ENCLog r -> IENCLog, r.el_id
  1581. | ENCMap r -> IENCMap, r.encm_id
  1582. | Assembly r -> IAssembly, r.a_id
  1583. | AssemblyProcessor r -> IAssemblyProcessor, r.ap_id
  1584. | AssemblyOS r -> IAssemblyOS, r.aos_id
  1585. | AssemblyRef r -> IAssemblyRef, r.ar_id
  1586. | AssemblyRefProcessor r -> IAssemblyRefProcessor, r.arp_id
  1587. | AssemblyRefOS r -> IAssemblyRefOS, r.aros_id
  1588. | File r -> IFile, r.file_id
  1589. | ExportedType r -> IExportedType, r.et_id
  1590. | ManifestResource r -> IManifestResource, r.mr_id
  1591. | NestedClass r -> INestedClass, r.nc_id
  1592. | GenericParam r -> IGenericParam, r.gp_id
  1593. | MethodSpec r -> IMethodSpec, r.mspec_id
  1594. | GenericParamConstraint r -> IGenericParamConstraint, r.gc_id
  1595. | _ -> assert false
  1596. let add_relation ctx key v =
  1597. let ptr = get_meta_pointer key in
  1598. Hashtbl.add ctx.relations ptr v
  1599. let read_table_at ctx tbl n last pos =
  1600. (* print_endline ("rr " ^ string_of_int (n+1)); *)
  1601. let s = ctx.meta_stream in
  1602. match get_table ctx tbl (n+1 (* indices start at 1 *)) with
  1603. | Module m ->
  1604. let pos, gen = sread_ui16 s pos in
  1605. let pos, name = read_sstring_idx ctx pos in
  1606. let pos, vid = read_sguid_idx ctx pos in
  1607. let pos, encid = read_sguid_idx ctx pos in
  1608. let pos, encbase_id = read_sguid_idx ctx pos in
  1609. m.md_generation <- gen;
  1610. m.md_name <- name;
  1611. m.md_vid <- vid;
  1612. m.md_encid <- encid;
  1613. m.md_encbase_id <- encbase_id;
  1614. pos, Module m
  1615. | TypeRef tr ->
  1616. let pos, scope = sread_from_table ctx false IResolutionScope s pos in
  1617. let pos, name = read_sstring_idx ctx pos in
  1618. let pos, ns = read_sstring_idx ctx pos in
  1619. tr.tr_resolution_scope <- scope;
  1620. tr.tr_name <- name;
  1621. tr.tr_namespace <- parse_ns ns;
  1622. (* print_endline name; *)
  1623. (* print_endline ns; *)
  1624. pos, TypeRef tr
  1625. | TypeDef td ->
  1626. let startpos = pos in
  1627. let pos, flags = sread_i32 s pos in
  1628. let pos, name = read_sstring_idx ctx pos in
  1629. let pos, ns = read_sstring_idx ctx pos in
  1630. let ns = parse_ns ns in
  1631. let pos, extends = sread_from_table_opt ctx false ITypeDefOrRef s pos in
  1632. let field_offset = pos - startpos in
  1633. let pos, flist_begin = ctx.table_sizes.(int_of_table IField) s pos in
  1634. let method_offset = pos - startpos in
  1635. let pos, mlist_begin = ctx.table_sizes.(int_of_table IMethod) s pos in
  1636. td.td_flags <- type_def_flags_of_int flags;
  1637. td.td_name <- name;
  1638. td.td_namespace <- ns;
  1639. td.td_extends <- extends;
  1640. td.td_field_list <- List.rev_map get_field (read_list ctx IField IFieldPtr flist_begin field_offset last pos);
  1641. td.td_method_list <- List.rev_map get_method (read_list ctx IMethod IMethodPtr mlist_begin method_offset last pos);
  1642. List.iter (fun m -> m.m_declaring <- Some td) td.td_method_list;
  1643. let path = get_path (TypeDef td) in
  1644. Hashtbl.add ctx.typedefs path td;
  1645. (* print_endline "Type Def!"; *)
  1646. (* print_endline name; *)
  1647. (* print_endline ns; *)
  1648. pos, TypeDef td
  1649. | FieldPtr fp ->
  1650. let pos, field = sread_from_table ctx false IField s pos in
  1651. let field = get_field field in
  1652. fp.fp_field <- field;
  1653. pos, FieldPtr fp
  1654. | Field f ->
  1655. let pos, flags = sread_ui16 s pos in
  1656. let pos, name = read_sstring_idx ctx pos in
  1657. (* print_endline ("FIELD NAME " ^ name); *)
  1658. let pos, ilsig = read_field_ilsig_idx ctx pos in
  1659. (* print_endline (ilsig_s ilsig); *)
  1660. f.f_flags <- field_flags_of_int flags;
  1661. f.f_name <- name;
  1662. f.f_signature <- ilsig;
  1663. pos, Field f
  1664. | MethodPtr mp ->
  1665. let pos, m = sread_from_table ctx false IMethod s pos in
  1666. let m = get_method m in
  1667. mp.mp_method <- m;
  1668. pos, MethodPtr mp
  1669. | Method m ->
  1670. let startpos = pos in
  1671. let pos, rva = sread_i32 s pos in
  1672. let pos, iflags = sread_ui16 s pos in
  1673. let pos, flags = sread_ui16 s pos in
  1674. let pos, name = read_sstring_idx ctx pos in
  1675. let pos, ilsig = read_method_ilsig_idx ctx pos in
  1676. let offset = pos - startpos in
  1677. let pos, paramlist = ctx.table_sizes.(int_of_table IParam) s pos in
  1678. m.m_rva <- Int32.of_int rva;
  1679. m.m_flags <- method_flags_of_int iflags flags;
  1680. m.m_name <- name;
  1681. m.m_signature <- ilsig;
  1682. m.m_param_list <- List.rev_map get_param (read_list ctx IParam IParamPtr paramlist offset last pos);
  1683. pos, Method m
  1684. | ParamPtr pp ->
  1685. let pos, p = sread_from_table ctx false IParam s pos in
  1686. let p = get_param p in
  1687. pp.pp_param <- p;
  1688. pos, ParamPtr pp
  1689. | Param p ->
  1690. let pos, flags = sread_ui16 s pos in
  1691. let pos, sequence = sread_ui16 s pos in
  1692. let pos, name = read_sstring_idx ctx pos in
  1693. p.p_flags <- param_flags_of_int flags;
  1694. p.p_sequence <- sequence;
  1695. p.p_name <- name;
  1696. pos, Param p
  1697. | InterfaceImpl ii ->
  1698. let pos, cls = sread_from_table ctx false ITypeDef s pos in
  1699. add_relation ctx cls (InterfaceImpl ii);
  1700. let cls = get_type_def cls in
  1701. let pos, interface = sread_from_table ctx false ITypeDefOrRef s pos in
  1702. ii.ii_class <- cls;
  1703. ii.ii_interface <- interface;
  1704. pos, InterfaceImpl ii
  1705. | MemberRef mr ->
  1706. let pos, cls = sread_from_table ctx false IMemberRefParent s pos in
  1707. let pos, name = read_sstring_idx ctx pos in
  1708. (* print_endline name; *)
  1709. (* let pos, signature = read_ilsig_idx ctx pos in *)
  1710. let pos, signature = read_field_ilsig_idx ~force_field:false ctx pos in
  1711. (* print_endline (ilsig_s signature); *)
  1712. mr.memr_class <- cls;
  1713. mr.memr_name <- name;
  1714. mr.memr_signature <- signature;
  1715. add_relation ctx cls (MemberRef mr);
  1716. pos, MemberRef mr
  1717. | Constant c ->
  1718. let pos, ctype = read_constant_type ctx s pos in
  1719. let pos = pos+1 in
  1720. let pos, parent = sread_from_table ctx false IHasConstant s pos in
  1721. let pos, blobpos = if ctx.blob_offset = 2 then
  1722. sread_ui16 s pos
  1723. else
  1724. sread_i32 s pos
  1725. in
  1726. let blob = ctx.blob_stream in
  1727. let blobpos, _ = read_compressed_i32 blob blobpos in
  1728. let _, value = read_constant ctx ctype blob blobpos in
  1729. c.c_type <- ctype;
  1730. c.c_parent <- parent;
  1731. c.c_value <- value;
  1732. add_relation ctx parent (Constant c);
  1733. pos, Constant c
  1734. | CustomAttribute ca ->
  1735. let pos, parent = sread_from_table ctx false IHasCustomAttribute s pos in
  1736. let pos, t = sread_from_table ctx false ICustomAttributeType s pos in
  1737. let pos = read_custom_attr_idx ctx ca t pos in
  1738. ca.ca_parent <- parent;
  1739. ca.ca_type <- t;
  1740. ca.ca_value <- None; (* this will be delayed by read_custom_attr_idx *)
  1741. add_relation ctx parent (CustomAttribute ca);
  1742. pos, CustomAttribute ca
  1743. | FieldMarshal fm ->
  1744. let pos, parent = sread_from_table ctx false IHasFieldMarshal s pos in
  1745. let pos, nativesig = read_nativesig_idx ctx s pos in
  1746. fm.fm_parent <- parent;
  1747. fm.fm_native_type <- nativesig;
  1748. add_relation ctx parent (FieldMarshal fm);
  1749. pos, FieldMarshal fm
  1750. | DeclSecurity ds ->
  1751. let pos, action = sread_ui16 s pos in
  1752. let action = action_security_of_int action in
  1753. let pos, parent = sread_from_table ctx false IHasDeclSecurity s pos in
  1754. let pos, permission_set = read_sblob_idx ctx pos in
  1755. ds.ds_action <- action;
  1756. ds.ds_parent <- parent;
  1757. ds.ds_permission_set <- permission_set;
  1758. add_relation ctx parent (DeclSecurity ds);
  1759. pos, DeclSecurity ds
  1760. | ClassLayout cl ->
  1761. let pos, psize = sread_ui16 s pos in
  1762. let pos, csize = sread_i32 s pos in
  1763. let pos, parent = sread_from_table ctx false ITypeDef s pos in
  1764. add_relation ctx parent (ClassLayout cl);
  1765. let parent = get_type_def parent in
  1766. cl.cl_packing_size <- psize;
  1767. cl.cl_class_size <- csize;
  1768. cl.cl_parent <- parent;
  1769. pos, ClassLayout cl
  1770. | FieldLayout fl ->
  1771. let pos, offset = sread_i32 s pos in
  1772. let pos, field = sread_from_table ctx false IField s pos in
  1773. fl.fl_offset <- offset;
  1774. fl.fl_field <- get_field field;
  1775. add_relation ctx field (FieldLayout fl);
  1776. pos, FieldLayout fl
  1777. | StandAloneSig sa ->
  1778. let pos, ilsig = read_field_ilsig_idx ~force_field:false ctx pos in
  1779. (* print_endline (ilsig_s ilsig); *)
  1780. sa.sa_signature <- ilsig;
  1781. pos, StandAloneSig sa
  1782. | EventMap em ->
  1783. let startpos = pos in
  1784. let pos, parent = sread_from_table ctx false ITypeDef s pos in
  1785. let offset = pos - startpos in
  1786. let pos, event_list = ctx.table_sizes.(int_of_table IEvent) s pos in
  1787. em.em_parent <- get_type_def parent;
  1788. em.em_event_list <- List.rev_map get_event (read_list ctx IEvent IEventPtr event_list offset last pos);
  1789. add_relation ctx parent (EventMap em);
  1790. pos, EventMap em
  1791. | EventPtr ep ->
  1792. let pos, event = sread_from_table ctx false IEvent s pos in
  1793. ep.ep_event <- get_event event;
  1794. pos, EventPtr ep
  1795. | Event e ->
  1796. let pos, flags = sread_ui16 s pos in
  1797. let pos, name = read_sstring_idx ctx pos in
  1798. let pos, event_type = sread_from_table ctx false ITypeDefOrRef s pos in
  1799. e.e_flags <- event_flags_of_int flags;
  1800. e.e_name <- name;
  1801. (* print_endline name; *)
  1802. e.e_event_type <- event_type;
  1803. add_relation ctx event_type (Event e);
  1804. pos, Event e
  1805. | PropertyMap pm ->
  1806. let startpos = pos in
  1807. let pos, parent = sread_from_table ctx false ITypeDef s pos in
  1808. let offset = pos - startpos in
  1809. let pos, property_list = ctx.table_sizes.(int_of_table IProperty) s pos in
  1810. pm.pm_parent <- get_type_def parent;
  1811. pm.pm_property_list <- List.rev_map get_property (read_list ctx IProperty IPropertyPtr property_list offset last pos);
  1812. add_relation ctx parent (PropertyMap pm);
  1813. pos, PropertyMap pm
  1814. | PropertyPtr pp ->
  1815. let pos, property = sread_from_table ctx false IProperty s pos in
  1816. pp.prp_property <- get_property property;
  1817. pos, PropertyPtr pp
  1818. | Property prop ->
  1819. let pos, flags = sread_ui16 s pos in
  1820. let pos, name = read_sstring_idx ctx pos in
  1821. let pos, t = read_field_ilsig_idx ~force_field:false ctx pos in
  1822. prop.prop_flags <- property_flags_of_int flags;
  1823. prop.prop_name <- name;
  1824. (* print_endline name; *)
  1825. prop.prop_type <- t;
  1826. (* print_endline (ilsig_s t); *)
  1827. pos, Property prop
  1828. | MethodSemantics ms ->
  1829. let pos, semantic = sread_ui16 s pos in
  1830. let pos, m = sread_from_table ctx false IMethod s pos in
  1831. let pos, association = sread_from_table ctx false IHasSemantics s pos in
  1832. ms.ms_semantic <- semantic_flags_of_int semantic;
  1833. ms.ms_method <- get_method m;
  1834. ms.ms_association <- association;
  1835. add_relation ctx m (MethodSemantics ms);
  1836. add_relation ctx association (MethodSemantics ms);
  1837. pos, MethodSemantics ms
  1838. | MethodImpl mi ->
  1839. let pos, cls = sread_from_table ctx false ITypeDef s pos in
  1840. let pos, method_body = sread_from_table ctx false IMethodDefOrRef s pos in
  1841. let pos, method_declaration = sread_from_table ctx false IMethodDefOrRef s pos in
  1842. mi.mi_class <- get_type_def cls;
  1843. mi.mi_method_body <- method_body;
  1844. mi.mi_method_declaration <- method_declaration;
  1845. add_relation ctx method_body (MethodImpl mi);
  1846. pos, MethodImpl mi
  1847. | ModuleRef modr ->
  1848. let pos, name = read_sstring_idx ctx pos in
  1849. modr.modr_name <- name;
  1850. (* print_endline name; *)
  1851. pos, ModuleRef modr
  1852. | TypeSpec ts ->
  1853. let pos, signature = read_ilsig_idx ctx pos in
  1854. (* print_endline (ilsig_s signature); *)
  1855. ts.ts_signature <- signature;
  1856. pos, TypeSpec ts
  1857. | ENCLog el ->
  1858. let pos, token = sread_i32 s pos in
  1859. let pos, func_code = sread_i32 s pos in
  1860. el.el_token <- token;
  1861. el.el_func_code <- func_code;
  1862. pos, ENCLog el
  1863. | ImplMap im ->
  1864. let pos, flags = sread_ui16 s pos in
  1865. let pos, forwarded = sread_from_table ctx false IMemberForwarded s pos in
  1866. let pos, import_name = read_sstring_idx ctx pos in
  1867. let pos, import_scope = sread_from_table ctx false IModuleRef s pos in
  1868. im.im_flags <- impl_flags_of_int flags;
  1869. im.im_forwarded <- forwarded;
  1870. im.im_import_name <- import_name;
  1871. im.im_import_scope <- get_module_ref import_scope;
  1872. add_relation ctx forwarded (ImplMap im);
  1873. pos, ImplMap im
  1874. | ENCMap em ->
  1875. let pos, token = sread_i32 s pos in
  1876. em.encm_token <- token;
  1877. pos, ENCMap em
  1878. | FieldRVA f ->
  1879. let pos, rva = sread_real_i32 s pos in
  1880. let pos, field = sread_from_table ctx false IField s pos in
  1881. f.fr_rva <- rva;
  1882. f.fr_field <- get_field field;
  1883. add_relation ctx field (FieldRVA f);
  1884. pos, FieldRVA f
  1885. | Assembly a ->
  1886. let pos, hash_algo = sread_i32 s pos in
  1887. let pos, major = sread_ui16 s pos in
  1888. let pos, minor = sread_ui16 s pos in
  1889. let pos, build = sread_ui16 s pos in
  1890. let pos, rev = sread_ui16 s pos in
  1891. let pos, flags = sread_i32 s pos in
  1892. let pos, public_key = read_sblob_idx ctx pos in
  1893. let pos, name = read_sstring_idx ctx pos in
  1894. let pos, locale = read_sstring_idx ctx pos in
  1895. a.a_hash_algo <- hash_algo_of_int hash_algo;
  1896. a.a_major <- major;
  1897. a.a_minor <- minor;
  1898. a.a_build <- build;
  1899. a.a_rev <- rev;
  1900. a.a_flags <- assembly_flags_of_int flags;
  1901. a.a_public_key <- public_key;
  1902. a.a_name <- name;
  1903. a.a_locale <- locale;
  1904. pos, Assembly a
  1905. | AssemblyProcessor ap ->
  1906. let pos, processor = sread_i32 s pos in
  1907. ap.ap_processor <- processor;
  1908. pos, AssemblyProcessor ap
  1909. | AssemblyOS aos ->
  1910. let pos, platform_id = sread_i32 s pos in
  1911. let pos, major = sread_i32 s pos in
  1912. let pos, minor = sread_i32 s pos in
  1913. aos.aos_platform_id <- platform_id;
  1914. aos.aos_major_version <- major;
  1915. aos.aos_minor_version <- minor;
  1916. pos, AssemblyOS aos
  1917. | AssemblyRef ar ->
  1918. let pos, major = sread_ui16 s pos in
  1919. let pos, minor = sread_ui16 s pos in
  1920. let pos, build = sread_ui16 s pos in
  1921. let pos, rev = sread_ui16 s pos in
  1922. let pos, flags = sread_i32 s pos in
  1923. let pos, public_key = read_sblob_idx ctx pos in
  1924. let pos, name = read_sstring_idx ctx pos in
  1925. let pos, locale = read_sstring_idx ctx pos in
  1926. let pos, hash_value = read_sblob_idx ctx pos in
  1927. ar.ar_major <- major;
  1928. ar.ar_minor <- minor;
  1929. ar.ar_build <- build;
  1930. ar.ar_rev <- rev;
  1931. ar.ar_flags <- assembly_flags_of_int flags;
  1932. ar.ar_public_key <- public_key;
  1933. ar.ar_name <- name;
  1934. (* print_endline name; *)
  1935. ar.ar_locale <- locale;
  1936. (* print_endline locale; *)
  1937. ar.ar_hash_value <- hash_value;
  1938. pos, AssemblyRef ar
  1939. | AssemblyRefProcessor arp ->
  1940. let pos, processor = sread_i32 s pos in
  1941. let pos, assembly_ref = sread_from_table ctx false IAssemblyRef s pos in
  1942. arp.arp_processor <- processor;
  1943. arp.arp_assembly_ref <- get_assembly_ref assembly_ref;
  1944. pos, AssemblyRefProcessor arp
  1945. | AssemblyRefOS aros ->
  1946. let pos, platform_id = sread_i32 s pos in
  1947. let pos, major = sread_i32 s pos in
  1948. let pos, minor = sread_i32 s pos in
  1949. let pos, assembly_ref = sread_from_table ctx false IAssemblyRef s pos in
  1950. aros.aros_platform_id <- platform_id;
  1951. aros.aros_major <- major;
  1952. aros.aros_minor <- minor;
  1953. aros.aros_assembly_ref <- get_assembly_ref assembly_ref;
  1954. pos, AssemblyRefOS aros
  1955. | File file ->
  1956. let pos, flags = sread_i32 s pos in
  1957. let pos, name = read_sstring_idx ctx pos in
  1958. let pos, hash_value = read_sblob_idx ctx pos in
  1959. file.file_flags <- file_flag_of_int flags;
  1960. file.file_name <- name;
  1961. (* print_endline ("file " ^ name); *)
  1962. file.file_hash_value <- hash_value;
  1963. pos, File file
  1964. | ExportedType et ->
  1965. let pos, flags = sread_i32 s pos in
  1966. let pos, type_def_id = sread_i32 s pos in
  1967. let pos, type_name = read_sstring_idx ctx pos in
  1968. let pos, type_namespace = read_sstring_idx ctx pos in
  1969. let pos, impl = sread_from_table ctx false IImplementation s pos in
  1970. et.et_flags <- type_def_flags_of_int flags;
  1971. et.et_type_def_id <- type_def_id;
  1972. et.et_type_name <- type_name;
  1973. et.et_type_namespace <- parse_ns type_namespace;
  1974. et.et_implementation <- impl;
  1975. add_relation ctx impl (ExportedType et);
  1976. pos, ExportedType et
  1977. | ManifestResource mr ->
  1978. let pos, offset = sread_i32 s pos in
  1979. let pos, flags = sread_i32 s pos in
  1980. (* printf "offset 0x%x flags 0x%x\n" offset flags; *)
  1981. let pos, name = read_sstring_idx ctx pos in
  1982. let rpos, i = ctx.table_sizes.(int_of_table IImplementation) s pos in
  1983. let pos, impl =
  1984. if i = 0 then
  1985. rpos, None
  1986. else
  1987. let pos, ret = sread_from_table ctx false IImplementation s pos in
  1988. add_relation ctx ret (ManifestResource mr);
  1989. pos, Some ret
  1990. in
  1991. mr.mr_offset <- offset;
  1992. mr.mr_flags <- manifest_resource_flag_of_int flags;
  1993. mr.mr_name <- name;
  1994. mr.mr_implementation <- impl;
  1995. pos, ManifestResource mr
  1996. | NestedClass nc ->
  1997. let pos, nested = sread_from_table ctx false ITypeDef s pos in
  1998. let pos, enclosing = sread_from_table ctx false ITypeDef s pos in
  1999. nc.nc_nested <- get_type_def nested;
  2000. nc.nc_enclosing <- get_type_def enclosing;
  2001. assert (nc.nc_nested.td_extra_enclosing = None);
  2002. nc.nc_nested.td_extra_enclosing <- Some nc.nc_enclosing;
  2003. add_relation ctx enclosing (NestedClass nc);
  2004. pos, NestedClass nc
  2005. | GenericParam gp ->
  2006. let pos, number = sread_ui16 s pos in
  2007. let pos, flags = sread_ui16 s pos in
  2008. let pos, owner = sread_from_table ctx false ITypeOrMethodDef s pos in
  2009. let spos, nidx =
  2010. if ctx.strings_offset = 2 then
  2011. sread_ui16 s pos
  2012. else
  2013. sread_i32 s pos
  2014. in
  2015. let pos, name =
  2016. if nidx = 0 then
  2017. spos, None
  2018. else
  2019. let pos, ret = read_sstring_idx ctx pos in
  2020. (* print_endline ret; *)
  2021. pos, Some ret
  2022. in
  2023. gp.gp_number <- number;
  2024. gp.gp_flags <- generic_flags_of_int flags;
  2025. gp.gp_owner <- owner;
  2026. gp.gp_name <- name;
  2027. add_relation ctx owner (GenericParam gp);
  2028. pos, GenericParam gp
  2029. | MethodSpec mspec ->
  2030. let pos, meth = sread_from_table ctx false IMethodDefOrRef s pos in
  2031. let pos, instantiation = read_method_ilsig_idx ctx pos in
  2032. (* print_endline (ilsig_s instantiation); *)
  2033. mspec.mspec_method <- meth;
  2034. mspec.mspec_instantiation <- instantiation;
  2035. add_relation ctx meth (MethodSpec mspec);
  2036. pos, MethodSpec mspec
  2037. | GenericParamConstraint gc ->
  2038. let pos, owner = sread_from_table ctx false IGenericParam s pos in
  2039. let pos, c = sread_from_table ctx false ITypeDefOrRef s pos in
  2040. gc.gc_owner <- get_generic_param owner;
  2041. gc.gc_constraint <- c;
  2042. add_relation ctx owner (GenericParamConstraint gc);
  2043. pos, GenericParamConstraint gc
  2044. | _ -> assert false
  2045. (* ******* META READING ********* *)
  2046. let preset_sizes ctx rows =
  2047. Array.iteri (fun n r -> match r with
  2048. | false,_ -> ()
  2049. | true,nrows ->
  2050. (* printf "table %d nrows %d\n" n nrows; *)
  2051. let tbl = table_of_int n in
  2052. ctx.tables.(n) <- DynArray.init (nrows) (fun id -> mk_meta tbl (id+1))
  2053. ) rows
  2054. (* let read_ *)
  2055. let read_meta ctx =
  2056. (* read header *)
  2057. let s = ctx.meta_stream in
  2058. let pos = 4 + 1 + 1 in
  2059. let flags = sget s pos in
  2060. List.iter (fun i -> if flags land i = i then match i with
  2061. | 0x01 ->
  2062. ctx.strings_offset <- 4
  2063. | 0x02 ->
  2064. ctx.guid_offset <- 4
  2065. | 0x04 ->
  2066. ctx.blob_offset <- 4
  2067. | 0x20 ->
  2068. assert (not ctx.compressed);
  2069. ctx.meta_edit_continue <- true
  2070. | 0x80 ->
  2071. assert (not ctx.compressed);
  2072. ctx.meta_has_deleted <- true
  2073. | _ -> assert false
  2074. ) [0x01;0x02;0x04;0x20;0x80];
  2075. let rid = sget s (pos+1) in
  2076. ignore rid;
  2077. let pos = pos + 2 in
  2078. let mask = Array.init 8 ( fun n -> sget s (pos + n) ) in
  2079. (* loop over masks and check which table is set *)
  2080. let set_table = Array.init 64 (fun n ->
  2081. let idx = n / 8 in
  2082. let bit = n mod 8 in
  2083. (mask.(idx) lsr bit) land 0x1 = 0x1
  2084. ) in
  2085. let pos = ref (pos + 8 + 8) in (* there is an extra 'sorted' field, which we do not use *)
  2086. let rows = Array.mapi (fun i b -> match b with
  2087. | false -> false,0
  2088. | true ->
  2089. let nidx, nrows = sread_i32 s !pos in
  2090. if nrows > 0xFFFF then ctx.table_sizes.(i) <- sread_i32;
  2091. pos := nidx;
  2092. true,nrows
  2093. ) set_table in
  2094. set_coded_sizes ctx rows;
  2095. (* pre-set all sizes *)
  2096. preset_sizes ctx rows;
  2097. Array.iteri (fun n r -> match r with
  2098. | false,_ -> ()
  2099. | true,nrows ->
  2100. (* print_endline (string_of_int n); *)
  2101. let fn = read_table_at ctx (table_of_int n) in
  2102. let rec loop_fn n =
  2103. if n = nrows then
  2104. ()
  2105. else begin
  2106. let p, _ = fn n (n = (nrows-1)) !pos in
  2107. pos := p;
  2108. loop_fn (n+1)
  2109. end
  2110. in
  2111. loop_fn 0
  2112. ) rows;
  2113. ()
  2114. let read_padded i npad =
  2115. let buf = Buffer.create 10 in
  2116. let rec loop n =
  2117. let chr = read i in
  2118. if chr = '\x00' then begin
  2119. let npad = n land 0x3 in
  2120. if npad <> 0 then ignore (nread i (4 - npad));
  2121. Buffer.contents buf
  2122. end else begin
  2123. Buffer.add_char buf chr;
  2124. if n = npad then
  2125. Buffer.contents buf
  2126. else
  2127. loop (n+1)
  2128. end
  2129. in
  2130. loop 1
  2131. let read_meta_tables pctx header module_cache =
  2132. let i = pctx.r.i in
  2133. seek_rva pctx (fst header.clr_meta);
  2134. let magic = nread_string i 4 in
  2135. if magic <> "BSJB" then error ("Error reading metadata table: Expected magic 'BSJB'. Got " ^ magic);
  2136. let major = read_ui16 i in
  2137. let minor = read_ui16 i in
  2138. ignore major; ignore minor; (* no use for them *)
  2139. ignore (read_i32 i); (* reserved *)
  2140. let vlen = read_i32 i in
  2141. let ver = nread i vlen in
  2142. ignore ver;
  2143. (* meta storage header *)
  2144. ignore (read_ui16 i); (* reserved *)
  2145. let nstreams = read_ui16 i in
  2146. let rec streams n acc =
  2147. let offset = read_i32 i in
  2148. let size = read_real_i32 i in
  2149. let name = read_padded i 32 in
  2150. let acc = {
  2151. str_offset = offset;
  2152. str_size = size;
  2153. str_name = name;
  2154. } :: acc in
  2155. if (n+1) = nstreams then
  2156. acc
  2157. else
  2158. streams (n+1) acc
  2159. in
  2160. let streams = streams 0 [] in
  2161. (* streams *)
  2162. let compressed = ref None in
  2163. let sstrings = ref "" in
  2164. let sblob = ref "" in
  2165. let sguid = ref "" in
  2166. let sus = ref "" in
  2167. let smeta = ref "" in
  2168. let extra = ref [] in
  2169. List.iter (fun s ->
  2170. let rva = Int32.add (fst header.clr_meta) (Int32.of_int s.str_offset) in
  2171. seek_rva pctx rva;
  2172. match String.lowercase s.str_name with
  2173. | "#guid" ->
  2174. sguid := nread_string i (Int32.to_int s.str_size)
  2175. | "#strings" ->
  2176. sstrings := nread_string i (Int32.to_int s.str_size)
  2177. | "#us" ->
  2178. sus := nread_string i (Int32.to_int s.str_size)
  2179. | "#blob" ->
  2180. sblob := nread_string i (Int32.to_int s.str_size)
  2181. | "#~" ->
  2182. assert (Option.is_none !compressed);
  2183. compressed := Some true;
  2184. smeta := nread_string i (Int32.to_int s.str_size)
  2185. | "#-" ->
  2186. assert (Option.is_none !compressed);
  2187. compressed := Some false;
  2188. smeta := nread_string i (Int32.to_int s.str_size)
  2189. | _ ->
  2190. extra := s :: !extra
  2191. ) streams;
  2192. let compressed = match !compressed with
  2193. | None -> error "No compressed or uncompressed metadata streams was found!"
  2194. | Some c -> c
  2195. in
  2196. let tables = Array.init 64 (fun _ -> DynArray.create ()) in
  2197. let ctx = {
  2198. compressed = compressed;
  2199. strings_stream = !sstrings;
  2200. strings_offset = 2;
  2201. blob_stream = !sblob;
  2202. blob_offset = 2;
  2203. guid_stream = !sguid;
  2204. guid_offset = 2;
  2205. us_stream = !sus;
  2206. meta_stream = !smeta;
  2207. meta_edit_continue = false;
  2208. meta_has_deleted = false;
  2209. module_cache = module_cache;
  2210. extra_streams = !extra;
  2211. relations = Hashtbl.create 64;
  2212. typedefs = Hashtbl.create 64;
  2213. tables = tables;
  2214. table_sizes = Array.make (max_clr_meta_idx+1) sread_ui16;
  2215. delays = [];
  2216. } in
  2217. read_meta ctx;
  2218. let delays = ctx.delays in
  2219. ctx.delays <- [];
  2220. List.iter (fun fn -> fn()) delays;
  2221. assert (ctx.delays = []);
  2222. {
  2223. il_tables = ctx.tables;
  2224. il_relations = ctx.relations;
  2225. il_typedefs = ctx.typedefs;
  2226. }