Metadata.cs 155 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837
  1. using System;
  2. using System.IO;
  3. using System.Collections;
  4. using System.Text;
  5. using System.Reflection;
  6. namespace PEAPI {
  7. #region Enums
  8. /// <summary>
  9. /// flags for the assembly (.corflags)
  10. /// </summary>
  11. public enum CorFlags {CF_IL_ONLY = 1, CF_32_BITREQUIRED = 2,
  12. CF_STRONGNAMESIGNED = 8, CF_TRACKDEBUGDATA = 0x10000 }
  13. /// <summary>
  14. /// subsystem for the assembly (.subsystem)
  15. /// </summary>
  16. public enum SubSystem { Native = 1, Windows_GUI = 2,
  17. Windows_CUI = 3, OS2_CUI = 5, POSIX_CUI = 7, Native_Windows = 8,
  18. Windows_CE_GUI = 9}
  19. /// <summary>
  20. /// Hash algorithms for the assembly
  21. /// </summary>
  22. public enum HashAlgorithm { None, SHA1 }
  23. /// <summary>
  24. /// Attributes for this assembly
  25. /// </summary>
  26. public enum AssemAttr { Retargetable = 0x100, EnableJITCompileTracking = 0x8000,
  27. DisableJITCompileOptimizer = 0x4000}
  28. /// <summary>
  29. /// Method call conventions
  30. /// </summary>
  31. [Flags]
  32. public enum CallConv { Default, Cdecl, Stdcall, Thiscall,
  33. Fastcall, Vararg, Instance = 0x20, Generic = 0x10, InstanceExplicit = 0x60 }
  34. /// <summary>
  35. /// Type custom modifier
  36. /// </summary>
  37. public enum CustomModifier { modreq = 0x1F, modopt };
  38. /// <summary>
  39. /// Attibutes for a class
  40. /// </summary>
  41. [Flags]
  42. public enum TypeAttr {Private, Public, NestedPublic, NestedPrivate,
  43. NestedFamily, NestedAssembly, NestedFamAndAssem, NestedFamOrAssem,
  44. SequentialLayout, ExplicitLayout = 0x10, Interface = 0x20,
  45. Abstract = 0x80, PublicAbstract = 0x81, Sealed = 0x100,
  46. PublicSealed = 0x101, SpecialName = 0x400, RTSpecialName = 0x800,
  47. Import = 0x1000, Serializable = 0x2000, UnicodeClass = 0x10000,
  48. AutoClass = 0x20000, HasSecurity = 0x40000, BeforeFieldInit = 0x100000,
  49. VisibilityMask = 0x07 }
  50. /// <summary>
  51. /// Attributes for a field
  52. /// </summary>
  53. public enum FieldAttr {Default, Private, FamAndAssem, Assembly,
  54. Family, FamOrAssem, Public, Static = 0x10, PublicStatic = 0x16,
  55. Initonly = 0x20, Literal = 0x40, Notserialized = 0x80,
  56. SpecialName = 0x200, RTSpecialName = 0x400, HasFieldMarshal = 0x1000 }
  57. /// <summary>
  58. /// Attributes for a method
  59. /// </summary>
  60. public enum MethAttr { Default, Private, FamAndAssem, Assembly,
  61. Family, FamOrAssem, Public, Static = 0x0010, PublicStatic = 0x16,
  62. Final = 0x0020, PublicStaticFinal = 0x36, Virtual = 0x0040,
  63. PrivateVirtual, PublicVirtual = 0x0046, HideBySig = 0x0080,
  64. NewSlot = 0x0100, Abstract = 0x0400, SpecialName = 0x0800,
  65. RTSpecialName = 0x1000, SpecialRTSpecialName = 0x1800,
  66. HasSecurity = 0x4000, RequireSecObject = 0x8000}
  67. /// <summary>
  68. /// Attributes for .pinvokeimpl method declarations
  69. /// </summary>
  70. public enum PInvokeAttr { nomangle = 1, ansi = 2, unicode = 4, autochar = 6,
  71. bestfit_on = 0x0010, bestfit_off = 0x0020, bestfit_mask = 0x0030,
  72. lasterr = 0x0040, winapi = 0x0100, cdecl = 0x0200,
  73. stdcall = 0x0300, thiscall = 0x0400, fastcall = 0x0500,
  74. charmaperror_on = 0x1000, charmaperror_off = 0x2000
  75. }
  76. /// <summary>
  77. /// Implementation attributes for a method
  78. /// </summary>
  79. public enum ImplAttr { IL, Native, Runtime = 0x03, Unmanaged = 0x04,
  80. ForwardRef = 0x10, PreserveSig = 0x0080, InternalCall = 0x1000,
  81. Synchronised = 0x0020, Synchronized = 0x0020, NoInLining = 0x0008, Optil = 0x0002}
  82. /// <summary>
  83. /// Modes for a parameter
  84. /// </summary>
  85. public enum ParamAttr { Default, In, Out, Opt = 16, HasDefault = 0x1000, HasFieldMarshal = 0x2000 }
  86. /// <summary>
  87. /// CIL instructions
  88. /// </summary>
  89. public enum Op { nop, breakOp, ldarg_0, ldarg_1, ldarg_2, ldarg_3,
  90. ldloc_0, ldloc_1, ldloc_2, ldloc_3, stloc_0, stloc_1, stloc_2, stloc_3,
  91. ldnull = 0x14, ldc_i4_m1, ldc_i4_0, ldc_i4_1, ldc_i4_2, ldc_i4_3,
  92. ldc_i4_4, ldc_i4_5, ldc_i4_6, ldc_i4_7, ldc_i4_8, dup = 0x25, pop,
  93. ret = 0x2A, ldind_i1 = 0x46, ldind_u1, ldind_i2, ldind_u2, ldind_i4,
  94. ldind_u4, ldind_i8, ldind_i, ldind_r4, ldind_r8, ldind_ref, stind_ref,
  95. stind_i1, stind_i2, stind_i4, stind_i8, stind_r4, stind_r8, add, sub, mul,
  96. div, div_un, rem, rem_un, and, or, xor, shl, shr, shr_un, neg, not,
  97. conv_i1, conv_i2, conv_i4, conv_i8, conv_r4, conv_r8, conv_u4, conv_u8,
  98. conv_r_un = 0x76, throwOp = 0x7A, conv_ovf_i1_un = 0x82, conv_ovf_i2_un,
  99. conv_ovf_i4_un, conv_ovf_i8_un, conf_ovf_u1_un, conv_ovf_u2_un,
  100. conv_ovf_u4_un, conv_ovf_u8_un, conv_ovf_i_un, conv_ovf_u_un,
  101. ldlen = 0x8E, ldelem_i1 = 0x90, ldelem_u1, ldelem_i2, ldelem_u2,
  102. ldelem_i4, ldelem_u4, ldelem_i8, ldelem_i, ldelem_r4, ldelem_r8,
  103. ldelem_ref, stelem_i, stelem_i1, stelem_i2, stelem_i4, stelem_i8, stelem_r4 = 0xA0, stelem_r8,
  104. stelem_ref, conv_ovf_i1 = 0xb3, conv_ovf_u1, conv_ovf_i2, conv_ovf_u2,
  105. conv_ovf_i4, conv_ovf_u4, conv_ovf_i8, conv_ovf_u8, ckfinite = 0xC3,
  106. conv_u2 = 0xD1, conv_u1, conv_i, conv_ovf_i, conv_ovf_u, add_ovf,
  107. add_ovf_un, mul_ovf, mul_ovf_un, sub_ovf, sub_ovf_un, endfinally,
  108. stind_i = 0xDF, conv_u, arglist = 0xFE00, ceq, cgt, cgt_un, clt, clt_un,
  109. localloc = 0xFE0F, endfilter = 0xFE11, volatile_ = 0xFE13, tail_,
  110. cpblk = 0xFE17, initblk, rethrow = 0xFE1A, refanytype = 0xFE1D, readonly_ = 0xFE1E }
  111. /// <summary>
  112. /// CIL instructions requiring an integer parameter
  113. /// </summary>
  114. public enum IntOp {ldarg_s = 0x0E, ldarga_s, starg_s, ldloc_s, ldloca_s,
  115. stloc_s, ldc_i4_s = 0x1F, ldc_i4, ldarg = 0xFE09,
  116. ldarga, starg, ldloc, ldloca, stloc, unaligned = 0xFE12 }
  117. /// <summary>
  118. /// CIL instructions requiring a field parameter
  119. /// </summary>
  120. public enum FieldOp {ldfld = 0x7B, ldflda, stfld, ldsfld, ldsflda,
  121. stsfld, ldtoken = 0xD0 }
  122. /// <summary>
  123. /// CIL instructions requiring a method parameter
  124. /// </summary>
  125. public enum MethodOp {jmp = 0x27, call, callvirt = 0x6F, newobj = 0x73,
  126. ldtoken = 0xD0, ldftn = 0xFE06, ldvirtfn }
  127. /// <summary>
  128. /// CIL instructions requiring a type parameter
  129. /// </summary>
  130. public enum TypeOp {cpobj = 0x70, ldobj, castclass = 0x74, isinst,
  131. unbox = 0x79, stobj = 0x81, box = 0x8C, newarr,
  132. ldelema = 0x8F, refanyval = 0xC2, mkrefany = 0xC6,
  133. ldtoken = 0xD0, initobj = 0xFE15, constrained = 0xFE16,
  134. sizeOf = 0xFE1C, ldelem = 0xA3, stelem = 0xA4, unbox_any }
  135. /// <summary>
  136. /// CIL branch instructions
  137. /// </summary>
  138. public enum BranchOp {
  139. // short branches
  140. br_s = 0x2B, brfalse_s, brtrue_s, beq_s, bge_s, bgt_s,
  141. ble_s, blt_s, bne_un_s, bge_un_s, bgt_un_s, ble_un_s, blt_un_s,
  142. // long branches
  143. br = 0x38, brfalse, brtrue, beq, bge, bgt, ble, blt,
  144. bne_un, bge_un, bgt_un, ble_un, blt_un,
  145. leave = 0xDD, leave_s }
  146. /// <summary>
  147. /// Index for all the tables in the meta data
  148. /// </summary>
  149. public enum MDTable { Module, TypeRef, TypeDef, Field = 0x04, Method = 0x06,
  150. Param = 0x08, InterfaceImpl, MemberRef, Constant, CustomAttribute,
  151. FieldMarshal, DeclSecurity, ClassLayout, FieldLayout, StandAloneSig,
  152. EventMap, Event = 0x14, PropertyMap, Property = 0x17, MethodSemantics,
  153. MethodImpl, ModuleRef, TypeSpec, ImplMap, FieldRVA, Assembly = 0x20,
  154. AssemblyProcessor, AssemblyOS, AssemblyRef, AssemblyRefProcessor,
  155. AssemblyRefOS, File, ExportedType, ManifestResource, NestedClass,
  156. GenericParam, MethodSpec, GenericParamConstraint }
  157. public enum SafeArrayType { int16 = 2, int32, float32, float64,
  158. currency, date, bstr, dispatch, error, boolean, variant, unknown,
  159. Decimal, int8 = 16, uint8, uint16, uint32, Int = 22, UInt }
  160. internal enum CIx { TypeDefOrRef, HasConst, HasCustomAttr, HasFieldMarshal,
  161. HasDeclSecurity, MemberRefParent, HasSemantics, MethodDefOrRef,
  162. MemberForwarded, Implementation, CustomAttributeType, ResolutionScope,
  163. TypeOrMethodDef, MaxCIx }
  164. internal enum MapType { eventMap, propertyMap, nestedClass }
  165. public enum ValueClass { ValueType, Enum }
  166. public enum GenParamType : byte {
  167. Var = 0x13, MVar = 0x1E
  168. }
  169. [Flags]
  170. public enum GenericParamAttributes : ushort {
  171. VarianceMask = 0x0003,
  172. NonVariant = 0x0000,
  173. Covariant = 0x0001,
  174. Contravariant = 0x0002,
  175. SpecialConstraintMask = 0x001c,
  176. ReferenceTypeConstraint = 0x0004,
  177. NotNullableValueTypeConstraint = 0x0008,
  178. DefaultConstructorConstrait = 0x0010
  179. }
  180. /* Taken from Mono.Cecil */
  181. public enum SecurityAction : short {
  182. Request = 1,
  183. Demand = 2,
  184. Assert = 3,
  185. Deny = 4,
  186. PermitOnly = 5,
  187. LinkDemand = 6,
  188. InheritDemand = 7,
  189. RequestMinimum = 8,
  190. RequestOptional = 9,
  191. RequestRefuse = 10,
  192. PreJitGrant = 11,
  193. PreJitDeny = 12,
  194. NonCasDemand = 13,
  195. NonCasLinkDemand = 14,
  196. NonCasInheritance = 15,
  197. LinkDemandChoice = 16,
  198. InheritDemandChoice = 17,
  199. DemandChoice = 18
  200. }
  201. #endregion
  202. /**************************************************************************/
  203. /// <summary>
  204. /// Base class for all Meta Data table elements
  205. /// </summary>
  206. public abstract class MetaDataElement: IComparable {
  207. protected ArrayList customAttributes;
  208. private uint row = 0;
  209. protected bool done = false;
  210. protected MDTable tabIx;
  211. protected bool sortTable = false;
  212. //Temporary hack..
  213. private bool has_custom_attrs = false;
  214. internal MetaDataElement() { }
  215. public uint Row {
  216. get {
  217. return row;
  218. }
  219. set {
  220. row = value;
  221. }
  222. }
  223. public bool HasCustomAttr {
  224. get { return has_custom_attrs; }
  225. set { has_custom_attrs = value; }
  226. }
  227. internal virtual uint GetCodedIx(CIx code) { return 0; }
  228. /// <summary>
  229. /// Add a custom attribute to this item
  230. /// </summary>
  231. /// <param name="ctorMeth">the constructor method for this attribute</param>
  232. /// <param name="val">the byte value of the parameters</param>
  233. public void AddCustomAttribute(Method ctorMeth, byte[] val)
  234. {
  235. if (customAttributes == null) {
  236. customAttributes = new ArrayList();
  237. }
  238. customAttributes.Add(new CustomAttribute(this,ctorMeth,val));
  239. }
  240. /// <summary>
  241. /// Add a custom attribute to this item
  242. /// </summary>
  243. /// <param name="ctorMeth">the constructor method for this attribute</param>
  244. /// <param name="val">the constant values of the parameters</param>
  245. public void AddCustomAttribute(Method ctorMeth, Constant[] cVals)
  246. {
  247. if (customAttributes == null) {
  248. customAttributes = new ArrayList();
  249. }
  250. // customAttributes.Add(new CustomAttribute(this,ctorMeth,cVals));
  251. }
  252. internal uint Token()
  253. {
  254. return (((uint)tabIx << 24) | row);
  255. }
  256. internal virtual void BuildTables(MetaData md)
  257. {
  258. done = true;
  259. }
  260. internal virtual uint Size(MetaData md)
  261. {
  262. return 0;
  263. }
  264. internal virtual void Write(FileImage output) { }
  265. internal virtual uint SortKey()
  266. {
  267. throw new PEFileException("Trying to sort table of " + this);
  268. //return 0;
  269. }
  270. internal virtual uint SortKey2()
  271. {
  272. return 0;
  273. }
  274. public int CompareTo(object obj)
  275. {
  276. uint otherKey = ((MetaDataElement)obj).SortKey();
  277. uint thisKey = SortKey();
  278. if (thisKey == otherKey) {
  279. otherKey = ((MetaDataElement)obj).SortKey2();
  280. thisKey = SortKey2();
  281. if (thisKey == otherKey)
  282. return 0;
  283. if (thisKey < otherKey)
  284. return -1;
  285. return 1;
  286. }
  287. if (thisKey < otherKey) return -1;
  288. return 1;
  289. }
  290. }
  291. /**************************************************************************/
  292. /// <summary>
  293. /// Layout information for a class (.class [sequential | explicit])
  294. /// </summary>
  295. internal class ClassLayout : MetaDataElement {
  296. ClassDef parent;
  297. ushort packSize = 0;
  298. uint classSize = 0;
  299. internal ClassLayout(int pack, int cSize, ClassDef par)
  300. {
  301. packSize = (ushort)pack;
  302. classSize = (uint)cSize;
  303. parent = par;
  304. tabIx = MDTable.ClassLayout;
  305. }
  306. internal sealed override uint Size(MetaData md)
  307. {
  308. return 6 + md.TableIndexSize(MDTable.TypeDef);
  309. }
  310. internal sealed override void Write(FileImage output)
  311. {
  312. output.Write(packSize);
  313. output.Write(classSize);
  314. output.WriteIndex(MDTable.TypeDef,parent.Row);
  315. }
  316. }
  317. /**************************************************************************/
  318. /// <summary>
  319. /// Summary description for ConstantElem.
  320. /// </summary>
  321. internal class ConstantElem : MetaDataElement {
  322. MetaDataElement parent;
  323. Constant cValue;
  324. uint valIx = 0;
  325. internal ConstantElem(MetaDataElement parent, Constant val)
  326. {
  327. this.parent = parent;
  328. cValue = val;
  329. tabIx = MDTable.Constant;
  330. sortTable = true;
  331. }
  332. internal override uint SortKey()
  333. {
  334. return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasConst])
  335. | parent.GetCodedIx(CIx.HasConst);
  336. }
  337. internal sealed override void BuildTables(MetaData md)
  338. {
  339. if (done) return;
  340. valIx = cValue.GetBlobIndex(md);
  341. done = true;
  342. }
  343. internal void AddToBlob(BinaryWriter bw)
  344. {
  345. cValue.Write(bw);
  346. }
  347. internal sealed override uint Size(MetaData md)
  348. {
  349. return 2 + md.CodedIndexSize(CIx.HasConst) + md.BlobIndexSize();
  350. }
  351. internal sealed override void Write(FileImage output)
  352. {
  353. output.Write(cValue.GetTypeIndex());
  354. output.Write((byte)0);
  355. output.WriteCodedIndex(CIx.HasConst,parent);
  356. output.BlobIndex(valIx);
  357. }
  358. }
  359. /**************************************************************************/
  360. /// <summary>
  361. /// Descriptor for a Custom Attribute (.custom)
  362. /// </summary>
  363. public class CustomAttribute : MetaDataElement {
  364. private static readonly ushort prolog = 0x0001;
  365. MetaDataElement parent;
  366. Method type;
  367. uint valIx;
  368. Constant cVal;
  369. byte[] byteVal;
  370. ushort numNamed = 0;
  371. ArrayList names, vals;
  372. internal CustomAttribute(MetaDataElement paren, Method constrType,
  373. Constant val) {
  374. parent = paren;
  375. type = constrType;
  376. cVal = val;
  377. tabIx = MDTable.CustomAttribute;
  378. }
  379. internal CustomAttribute(MetaDataElement paren, Method constrType,
  380. byte[] val) {
  381. parent = paren;
  382. type = constrType;
  383. tabIx = MDTable.CustomAttribute;
  384. byteVal = val;
  385. }
  386. internal override uint SortKey()
  387. {
  388. return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasCustomAttr])
  389. | parent.GetCodedIx(CIx.HasCustomAttr);
  390. }
  391. public void AddFieldOrProp(string name, Constant val)
  392. {
  393. if (numNamed == 0) {
  394. names = new ArrayList();
  395. vals = new ArrayList();
  396. }
  397. names.Add(name);
  398. vals.Add(val);
  399. }
  400. internal sealed override void BuildTables(MetaData md)
  401. {
  402. md.AddToTable(MDTable.CustomAttribute, this);
  403. if (byteVal == null) {
  404. valIx = 0;
  405. return;
  406. }
  407. BinaryWriter bw = new BinaryWriter(new MemoryStream());
  408. bw.Write(byteVal);
  409. MemoryStream str = (MemoryStream)bw.BaseStream;
  410. valIx = md.AddToBlobHeap(str.ToArray());
  411. }
  412. internal sealed override uint Size(MetaData md)
  413. {
  414. return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();
  415. }
  416. internal sealed override void Write(FileImage output)
  417. {
  418. output.WriteCodedIndex(CIx.HasCustomAttr,parent);
  419. output.WriteCodedIndex(CIx.CustomAttributeType,type);
  420. output.BlobIndex(valIx);
  421. }
  422. }
  423. /**************************************************************************/
  424. /// <summary>
  425. /// Descriptor for security permissions for a class or a method
  426. /// </summary>
  427. public abstract class BaseDeclSecurity : MetaDataElement {
  428. ushort action;
  429. MetaDataElement parent;
  430. uint permissionIx;
  431. internal BaseDeclSecurity(MetaDataElement paren, ushort act)
  432. {
  433. parent = paren;
  434. action = act;
  435. tabIx = MDTable.DeclSecurity;
  436. }
  437. internal override uint SortKey()
  438. {
  439. return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasDeclSecurity])
  440. | parent.GetCodedIx(CIx.HasDeclSecurity);
  441. }
  442. internal sealed override uint Size(MetaData md)
  443. {
  444. return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();
  445. }
  446. internal sealed override void BuildTables(MetaData md)
  447. {
  448. if (done) return;
  449. BinaryWriter bw = new BinaryWriter (new MemoryStream ());
  450. md.AddToTable (MDTable.DeclSecurity, this);
  451. MemoryStream str = (MemoryStream)bw.BaseStream;
  452. WriteSig (bw);
  453. permissionIx = md.AddToBlobHeap(str.ToArray());
  454. done = true;
  455. }
  456. internal abstract void WriteSig (BinaryWriter bw);
  457. internal sealed override void Write(FileImage output)
  458. {
  459. output.Write(action);
  460. output.WriteCodedIndex(CIx.HasDeclSecurity,parent);
  461. output.BlobIndex(permissionIx);
  462. }
  463. }
  464. public class DeclSecurity : BaseDeclSecurity {
  465. byte [] byteVal;
  466. internal DeclSecurity(MetaDataElement paren, ushort act, byte [] val)
  467. : base (paren, act)
  468. {
  469. byteVal = val;
  470. }
  471. internal override void WriteSig (BinaryWriter bw)
  472. {
  473. bw.Write (byteVal);
  474. }
  475. }
  476. public class DeclSecurity_20 : BaseDeclSecurity {
  477. PermissionSet ps;
  478. internal DeclSecurity_20 (MetaDataElement paren, ushort act, PermissionSet ps)
  479. : base (paren, act)
  480. {
  481. this.ps = ps;
  482. }
  483. internal override void WriteSig (BinaryWriter bw)
  484. {
  485. ps.Write (bw);
  486. }
  487. }
  488. public class PermissionMember {
  489. MemberTypes member_type;
  490. PEAPI.Type type;
  491. string name;
  492. object value;
  493. public PermissionMember (MemberTypes member_type, PEAPI.Type type, string name, object value)
  494. {
  495. this.member_type = member_type;
  496. this.type = type;
  497. this.name = name;
  498. this.value = value;
  499. }
  500. public void Write (BinaryWriter bw)
  501. {
  502. byte [] b;
  503. if (member_type == MemberTypes.Field)
  504. bw.Write ((byte) 0x53);
  505. else
  506. //Property
  507. bw.Write ((byte) 0x54);
  508. if (type is PrimitiveType) {
  509. bw.Write (type.GetTypeIndex ());
  510. } else {
  511. //must be enum
  512. bw.Write ((byte) 0x55); //ENUM
  513. b = Encoding.UTF8.GetBytes (((ClassRef) type).TypeName ());
  514. MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
  515. bw.Write (b);
  516. }
  517. b = Encoding.UTF8.GetBytes (name);
  518. MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
  519. bw.Write (b);
  520. ((Constant) value).Write (bw);
  521. }
  522. }
  523. public class Permission
  524. {
  525. PEAPI.Type type;
  526. //PermissionMembers
  527. ArrayList members;
  528. string name;
  529. public Permission (PEAPI.Type type, string name)
  530. {
  531. this.type = type;
  532. this.name = name;
  533. }
  534. public void AddMember (PEAPI.PermissionMember member)
  535. {
  536. if (members == null)
  537. members = new ArrayList ();
  538. members.Add (member);
  539. }
  540. public void Write (BinaryWriter bw)
  541. {
  542. byte [] b = Encoding.UTF8.GetBytes (name);
  543. MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
  544. bw.Write (b);
  545. BinaryWriter perm_writer = new BinaryWriter (new MemoryStream (), Encoding.Unicode);
  546. MemoryStream str = (MemoryStream) perm_writer.BaseStream;
  547. MetaData.CompressNum ((uint) members.Count, str);//number of params
  548. foreach (PermissionMember member in members)
  549. member.Write (perm_writer);
  550. bw.Write ((byte) str.Length); //(optional) parameters length
  551. bw.Write (str.ToArray ());
  552. }
  553. }
  554. public class PermissionSet
  555. {
  556. PEAPI.SecurityAction sec_action;
  557. ArrayList permissions;
  558. PEAPI.PermissionSet ps;
  559. public PermissionSet (PEAPI.SecurityAction sec_action)
  560. {
  561. this.sec_action = sec_action;
  562. }
  563. public void AddPermission (PEAPI.Permission perm)
  564. {
  565. if (permissions == null)
  566. permissions = new ArrayList ();
  567. permissions.Add (perm);
  568. }
  569. public void Write (BinaryWriter bw)
  570. {
  571. bw.Write ((byte) 0x2e);
  572. MetaData.CompressNum ((uint) permissions.Count, (MemoryStream) bw.BaseStream);
  573. foreach (Permission perm in permissions)
  574. perm.Write (bw);
  575. }
  576. }
  577. /**************************************************************************/
  578. /// <summary>
  579. /// Descriptor for layout information for a field
  580. /// </summary>
  581. public class FieldLayout : MetaDataElement {
  582. Field field;
  583. uint offset;
  584. internal FieldLayout(Field field, uint offset)
  585. {
  586. this.field = field;
  587. this.offset = offset;
  588. tabIx = MDTable.FieldLayout;
  589. }
  590. internal sealed override uint Size(MetaData md)
  591. {
  592. return 4 + md.TableIndexSize(MDTable.Field);
  593. }
  594. internal sealed override void Write(FileImage output)
  595. {
  596. output.Write(offset);
  597. output.WriteIndex(MDTable.Field,field.Row);
  598. }
  599. }
  600. /*****************************************************************************/
  601. /// <summary>
  602. /// Marshalling information for a field or param
  603. /// </summary>
  604. public class FieldMarshal : MetaDataElement {
  605. MetaDataElement field;
  606. NativeType nt;
  607. uint ntIx;
  608. internal FieldMarshal(MetaDataElement field, NativeType nType)
  609. {
  610. this.field = field;
  611. this.nt = nType;
  612. tabIx = MDTable.FieldMarshal;
  613. }
  614. internal override uint SortKey()
  615. {
  616. return (field.Row << MetaData.CIxShiftMap[(uint)CIx.HasFieldMarshal])
  617. | field.GetCodedIx(CIx.HasFieldMarshal);
  618. }
  619. internal sealed override void BuildTables(MetaData md)
  620. {
  621. if (done) return;
  622. ntIx = md.AddToBlobHeap(nt.ToBlob());
  623. done = true;
  624. }
  625. internal sealed override uint Size(MetaData md)
  626. {
  627. return md.CodedIndexSize(CIx.HasFieldMarshal) + md.BlobIndexSize();
  628. }
  629. internal sealed override void Write(FileImage output)
  630. {
  631. output.WriteCodedIndex(CIx.HasFieldMarshal,field);
  632. output.BlobIndex(ntIx);
  633. }
  634. }
  635. /**************************************************************************/
  636. /// <summary>
  637. /// Descriptor for the address of a field's value in the PE file
  638. /// </summary>
  639. public class FieldRVA : MetaDataElement {
  640. Field field;
  641. DataConstant data;
  642. internal FieldRVA(Field field, DataConstant data)
  643. {
  644. this.field = field;
  645. this.data = data;
  646. tabIx = MDTable.FieldRVA;
  647. }
  648. internal sealed override void BuildTables(MetaData md)
  649. {
  650. if (done) return;
  651. md.AddData(data);
  652. done = true;
  653. }
  654. internal sealed override uint Size(MetaData md)
  655. {
  656. return 4 + md.TableIndexSize(MDTable.Field);
  657. }
  658. internal sealed override void Write(FileImage output)
  659. {
  660. output.WriteDataRVA(data.DataOffset);
  661. output.WriteIndex(MDTable.Field,field.Row);
  662. }
  663. }
  664. /**************************************************************************/
  665. /// <summary>
  666. /// Descriptor for a file referenced in THIS assembly/module (.file)
  667. /// </summary>
  668. public class FileRef : MetaDataElement {
  669. private static readonly uint NoMetaData = 0x1;
  670. uint nameIx = 0, hashIx = 0;
  671. uint flags = 0;
  672. protected string name;
  673. internal FileRef(string name, byte[] hashBytes, bool metaData,
  674. bool entryPoint, MetaData md) {
  675. if (!metaData) flags = NoMetaData;
  676. if (entryPoint) md.SetEntryPoint(this);
  677. this.name = name;
  678. nameIx = md.AddToStringsHeap(name);
  679. hashIx = md.AddToBlobHeap(hashBytes);
  680. tabIx = MDTable.File;
  681. }
  682. internal FileRef(uint nameIx, byte[] hashBytes, bool metaData,
  683. bool entryPoint, MetaData md) {
  684. if (!metaData) flags = NoMetaData;
  685. if (entryPoint) md.SetEntryPoint(this);
  686. this.nameIx = nameIx;
  687. hashIx = md.AddToBlobHeap(hashBytes);
  688. tabIx = MDTable.File;
  689. }
  690. internal sealed override uint Size(MetaData md)
  691. {
  692. return 4 + md.StringsIndexSize() + md.BlobIndexSize();
  693. }
  694. internal sealed override void BuildTables(MetaData md)
  695. {
  696. md.AddToTable(MDTable.File,this);
  697. }
  698. internal sealed override void Write(FileImage output)
  699. {
  700. output.Write(flags);
  701. output.StringsIndex(nameIx);
  702. output.BlobIndex(hashIx);
  703. }
  704. internal sealed override uint GetCodedIx(CIx code)
  705. {
  706. switch (code) {
  707. case (CIx.HasCustomAttr) : return 16;
  708. case (CIx.Implementation) : return 0;
  709. }
  710. return 0;
  711. }
  712. }
  713. /**************************************************************************/
  714. /// <summary>
  715. /// Descriptor for pinvoke information for a method NOT YET IMPLEMENTED
  716. /// </summary>
  717. public class ImplMap : MetaDataElement {
  718. private static readonly ushort NoMangle = 0x01;
  719. ushort flags;
  720. Method meth;
  721. string importName;
  722. uint iNameIx;
  723. ModuleRef importScope;
  724. internal ImplMap(ushort flag, Method implMeth, string iName, ModuleRef mScope)
  725. {
  726. flags = flag;
  727. meth = implMeth;
  728. importName = iName;
  729. importScope = mScope;
  730. tabIx = MDTable.ImplMap;
  731. if (iName == null) flags |= NoMangle;
  732. //throw(new NotYetImplementedException("PInvoke "));
  733. }
  734. internal override uint SortKey()
  735. {
  736. return (meth.Row << MetaData.CIxShiftMap[(uint)CIx.MemberForwarded])
  737. | meth.GetCodedIx(CIx.MemberForwarded);
  738. }
  739. internal sealed override void BuildTables(MetaData md)
  740. {
  741. if (done) return;
  742. iNameIx = md.AddToStringsHeap(importName);
  743. done = true;
  744. }
  745. internal sealed override uint Size(MetaData md)
  746. {
  747. return 2+ md.CodedIndexSize(CIx.MemberForwarded) +
  748. md.StringsIndexSize() + md.TableIndexSize(MDTable.ModuleRef);
  749. }
  750. internal sealed override void Write(FileImage output)
  751. {
  752. output.Write(flags);
  753. output.WriteCodedIndex(CIx.MemberForwarded,meth);
  754. output.StringsIndex(iNameIx);
  755. output.WriteIndex(MDTable.ModuleRef,importScope.Row);
  756. }
  757. }
  758. /**************************************************************************/
  759. public class GenericParameter : MetaDataElement {
  760. MetaDataElement owner;
  761. MetaData metadata;
  762. public string name;
  763. uint nameIx;
  764. short index;
  765. GenericParamAttributes attr;
  766. internal GenericParameter (ClassDef owner, MetaData metadata,
  767. short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
  768. {
  769. }
  770. internal GenericParameter (MethodDef owner, MetaData metadata,
  771. short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
  772. {
  773. }
  774. private GenericParameter (MetaDataElement owner, MetaData metadata,
  775. short index, string name, GenericParamAttributes attr, bool nadda) {
  776. this.owner = owner;
  777. this.metadata = metadata;
  778. this.index = index;
  779. tabIx = MDTable.GenericParam;
  780. this.name = name;
  781. this.attr = attr;
  782. }
  783. internal override uint SortKey()
  784. {
  785. return (owner.Row << MetaData.CIxShiftMap[(uint)CIx.TypeOrMethodDef])
  786. | owner.GetCodedIx(CIx.TypeOrMethodDef);
  787. }
  788. internal override uint SortKey2 ()
  789. {
  790. return (uint) index;
  791. }
  792. public void AddConstraint (Type constraint)
  793. {
  794. metadata.AddToTable (MDTable.GenericParamConstraint,
  795. new GenericParamConstraint (this, constraint));
  796. }
  797. internal sealed override uint Size(MetaData md)
  798. {
  799. return (uint) (4 +
  800. md.CodedIndexSize(CIx.TypeOrMethodDef) +
  801. md.StringsIndexSize ());
  802. }
  803. internal sealed override void BuildTables(MetaData md)
  804. {
  805. if (done) return;
  806. nameIx = md.AddToStringsHeap(name);
  807. done = true;
  808. }
  809. internal sealed override void Write(FileImage output)
  810. {
  811. output.Write ((short) index);
  812. output.Write ((short) attr);
  813. output.WriteCodedIndex(CIx.TypeOrMethodDef, owner);
  814. output.StringsIndex (nameIx);
  815. }
  816. internal sealed override uint GetCodedIx(CIx code)
  817. {
  818. switch (code) {
  819. case (CIx.HasCustomAttr) : return 19;
  820. }
  821. return 0;
  822. }
  823. }
  824. internal class GenericParamConstraint : MetaDataElement {
  825. GenericParameter param;
  826. Type type;
  827. public GenericParamConstraint (GenericParameter param, Type type)
  828. {
  829. this.param = param;
  830. this.type = type;
  831. tabIx = MDTable.GenericParamConstraint;
  832. }
  833. internal override uint SortKey()
  834. {
  835. return param.Row;
  836. }
  837. internal sealed override uint Size(MetaData md)
  838. {
  839. return (uint) (md.TableIndexSize(MDTable.GenericParam) +
  840. md.CodedIndexSize(CIx.TypeDefOrRef));
  841. }
  842. internal sealed override void Write(FileImage output)
  843. {
  844. output.WriteIndex(MDTable.GenericParam, param.Row);
  845. output.WriteCodedIndex(CIx.TypeDefOrRef, type);
  846. }
  847. }
  848. internal class MethodSpec : Method {
  849. Method meth;
  850. GenericMethodSig g_sig;
  851. uint sidx;
  852. internal MethodSpec (Method meth, GenericMethodSig g_sig) : base ("")
  853. {
  854. this.meth = meth;
  855. this.g_sig = g_sig;
  856. tabIx = MDTable.MethodSpec;
  857. }
  858. internal override uint GetSigIx (MetaData md)
  859. {
  860. throw new Exception ("Should not be used.");
  861. }
  862. public override void AddCallConv (CallConv cconv)
  863. {
  864. throw new Exception ("Should not be used.");
  865. }
  866. internal sealed override void BuildTables (MetaData md)
  867. {
  868. if (done) return;
  869. sidx = g_sig.GetSigIx (md);
  870. done = true;
  871. }
  872. internal sealed override uint Size (MetaData md)
  873. {
  874. return (uint) (md.CodedIndexSize(CIx.MethodDefOrRef) +
  875. md.BlobIndexSize ());
  876. }
  877. internal sealed override void Write (FileImage output)
  878. {
  879. output.WriteCodedIndex (CIx.MethodDefOrRef, meth);
  880. output.BlobIndex (sidx);
  881. }
  882. internal sealed override void TypeSig (MemoryStream sig)
  883. {
  884. throw new Exception ("Should not be used.");
  885. }
  886. }
  887. /**************************************************************************/
  888. /// <summary>
  889. /// Descriptor for interface implemented by a class
  890. /// </summary>
  891. public class InterfaceImpl: MetaDataElement {
  892. ClassDef theClass;
  893. Class theInterface;
  894. internal InterfaceImpl(ClassDef theClass, Class theInterface)
  895. {
  896. this.theClass = theClass;
  897. this.theInterface = theInterface;
  898. tabIx = MDTable.InterfaceImpl;
  899. }
  900. internal sealed override uint Size(MetaData md)
  901. {
  902. return md.TableIndexSize(MDTable.TypeDef) +
  903. md.CodedIndexSize(CIx.TypeDefOrRef);
  904. }
  905. internal sealed override void Write(FileImage output)
  906. {
  907. output.WriteIndex(MDTable.TypeDef,theClass.Row);
  908. output.WriteCodedIndex(CIx.TypeDefOrRef,theInterface);
  909. }
  910. internal sealed override uint GetCodedIx(CIx code) { return 5; }
  911. internal override uint SortKey ()
  912. {
  913. return (theClass.Row << MetaData.CIxShiftMap[(uint)CIx.TypeDefOrRef])
  914. | theClass.GetCodedIx (CIx.TypeDefOrRef);
  915. }
  916. }
  917. /**************************************************************************/
  918. /// <summary>
  919. /// Descriptor for resources used in this PE file
  920. /// </summary>
  921. public class ManifestResource : MetaDataElement {
  922. public static readonly uint PublicResource = 0x1;
  923. public static readonly uint PrivateResource = 0x2;
  924. string mrName;
  925. MetaDataElement rRef;
  926. uint fileOffset;
  927. uint nameIx = 0;
  928. uint flags = 0;
  929. byte [] resourceBytes;
  930. public ManifestResource (string name, byte[] resBytes, uint flags)
  931. {
  932. InitResource (name, flags);
  933. this.resourceBytes = resBytes;
  934. }
  935. public ManifestResource(string name, uint flags, FileRef fileRef)
  936. {
  937. InitResource (name, flags);
  938. rRef = fileRef;
  939. }
  940. public ManifestResource(string name, uint flags, FileRef fileRef,
  941. uint fileIx) {
  942. InitResource (name, flags);
  943. rRef = fileRef;
  944. fileOffset = fileIx;
  945. }
  946. public ManifestResource(string name, uint flags, AssemblyRef assemRef)
  947. {
  948. InitResource (name, flags);
  949. rRef = assemRef;
  950. }
  951. internal ManifestResource (ManifestResource mres)
  952. {
  953. mrName = mres.mrName;
  954. flags = mres.flags;
  955. rRef = mres.rRef;
  956. fileOffset = mres.fileOffset;
  957. resourceBytes = mres.resourceBytes;
  958. }
  959. private void InitResource (string name, uint flags)
  960. {
  961. mrName = name;
  962. this.flags = flags;
  963. tabIx = MDTable.ManifestResource;
  964. }
  965. internal sealed override void BuildTables(MetaData md)
  966. {
  967. if (done) return;
  968. md.AddToTable (MDTable.ManifestResource, this);
  969. nameIx = md.AddToStringsHeap(mrName);
  970. if (resourceBytes != null) {
  971. if (rRef != null)
  972. throw new PEFileException ("Manifest Resource has byte value and file reference");
  973. fileOffset = md.AddResource(resourceBytes);
  974. } else {
  975. if (rRef == null)
  976. throw new PEFileException ("Manifest Resource has no implementation or value");
  977. rRef.BuildTables (md);
  978. }
  979. done = true;
  980. }
  981. internal sealed override uint Size(MetaData md)
  982. {
  983. return 8 + md.StringsIndexSize() +
  984. md.CodedIndexSize(CIx.Implementation);
  985. }
  986. internal sealed override void Write(FileImage output)
  987. {
  988. output.Write(fileOffset);
  989. output.Write(flags);
  990. output.StringsIndex(nameIx);
  991. output.WriteCodedIndex(CIx.Implementation,rRef);
  992. }
  993. internal sealed override uint GetCodedIx(CIx code) { return 18; }
  994. public string Name {
  995. get { return mrName; }
  996. set { mrName = value; }
  997. }
  998. }
  999. /**************************************************************************/
  1000. /// <summary>
  1001. /// Base class for elements in the PropertyMap, EventMap and
  1002. /// NestedClass MetaData tables
  1003. /// </summary>
  1004. public class MapElem : MetaDataElement {
  1005. ClassDef parent;
  1006. uint elemIx;
  1007. MDTable elemTable;
  1008. internal MapElem(ClassDef par, uint elIx, MDTable elemTab)
  1009. {
  1010. parent = par;
  1011. elemIx = elIx;
  1012. elemTable = elemTab;
  1013. }
  1014. internal sealed override uint Size(MetaData md)
  1015. {
  1016. return md.TableIndexSize(MDTable.TypeDef) + md.TableIndexSize(elemTable);
  1017. }
  1018. internal sealed override void Write(FileImage output)
  1019. {
  1020. output.WriteIndex(MDTable.TypeDef,parent.Row);
  1021. output.WriteIndex(elemTable,elemIx);
  1022. }
  1023. }
  1024. /**************************************************************************/
  1025. /// <summary>
  1026. /// Descriptor for an overriding method (.override)
  1027. /// </summary>
  1028. public class MethodImpl : MetaDataElement {
  1029. ClassDef parent;
  1030. Method header, body;
  1031. internal MethodImpl(ClassDef par, Method decl, Method bod)
  1032. {
  1033. parent = par;
  1034. header = decl;
  1035. body = bod;
  1036. tabIx = MDTable.MethodImpl;
  1037. }
  1038. internal sealed override uint Size(MetaData md)
  1039. {
  1040. return md.TableIndexSize(MDTable.TypeDef) + 2 * md.CodedIndexSize(CIx.MethodDefOrRef);
  1041. }
  1042. internal sealed override void Write(FileImage output)
  1043. {
  1044. output.WriteIndex(MDTable.TypeDef,parent.Row);
  1045. output.WriteCodedIndex(CIx.MethodDefOrRef,body);
  1046. output.WriteCodedIndex(CIx.MethodDefOrRef,header);
  1047. }
  1048. }
  1049. /**************************************************************************/
  1050. /// <summary>
  1051. /// Descriptor for Property and Event methods
  1052. /// </summary>
  1053. public class MethodSemantics : MetaDataElement {
  1054. Feature.MethodType type;
  1055. MethodDef meth;
  1056. Feature eventOrProp;
  1057. internal MethodSemantics(Feature.MethodType mType, MethodDef method, Feature feature)
  1058. {
  1059. type = mType;
  1060. meth = method;
  1061. eventOrProp = feature;
  1062. tabIx = MDTable.MethodSemantics;
  1063. }
  1064. internal override uint SortKey()
  1065. {
  1066. return (eventOrProp.Row << MetaData.CIxShiftMap [(uint)CIx.HasSemantics])
  1067. | eventOrProp.GetCodedIx (CIx.HasSemantics);
  1068. }
  1069. internal sealed override uint Size(MetaData md)
  1070. {
  1071. return 2 + md.TableIndexSize(MDTable.Method) + md.CodedIndexSize(CIx.HasSemantics);
  1072. }
  1073. internal sealed override void Write(FileImage output)
  1074. {
  1075. output.Write((ushort)type);
  1076. output.WriteIndex(MDTable.Method,meth.Row);
  1077. output.WriteCodedIndex(CIx.HasSemantics,eventOrProp);
  1078. }
  1079. }
  1080. /**************************************************************************/
  1081. /// <summary>
  1082. /// Descriptor for a parameter of a method defined in this assembly/module
  1083. /// </summary>
  1084. public class Param : MetaDataElement {
  1085. Type pType;
  1086. string pName;
  1087. internal ushort seqNo = 0;
  1088. ushort parMode;
  1089. ConstantElem defaultVal;
  1090. uint nameIx = 0;
  1091. FieldMarshal marshalInfo;
  1092. /// <summary>
  1093. /// Create a new parameter for a method
  1094. /// </summary>
  1095. /// <param name="mode">param mode (in, out, opt)</param>
  1096. /// <param name="parName">parameter name</param>
  1097. /// <param name="parType">parameter type</param>
  1098. public Param(ParamAttr mode, string parName, Type parType)
  1099. {
  1100. pName = parName;
  1101. pType = parType;
  1102. parMode = (ushort)mode;
  1103. tabIx = MDTable.Param;
  1104. }
  1105. public bool HasMarshalInfo {
  1106. get { return marshalInfo != null; }
  1107. }
  1108. /// <summary>
  1109. /// Add a default value to this parameter
  1110. /// </summary>
  1111. /// <param name="c">the default value for the parameter</param>
  1112. public void AddDefaultValue(Constant cVal)
  1113. {
  1114. defaultVal = new ConstantElem(this,cVal);
  1115. parMode |= (ushort) ParamAttr.HasDefault;
  1116. }
  1117. /// <summary>
  1118. /// Add marshalling information about this parameter
  1119. /// </summary>
  1120. public void AddMarshallInfo(NativeType marshallType)
  1121. {
  1122. parMode |= (ushort) ParamAttr.HasFieldMarshal;
  1123. marshalInfo = new FieldMarshal(this,marshallType);
  1124. }
  1125. internal Type GetParType() { return pType; }
  1126. internal sealed override void BuildTables(MetaData md)
  1127. {
  1128. if (done) return;
  1129. nameIx = md.AddToStringsHeap(pName);
  1130. if (defaultVal != null) {
  1131. md.AddToTable(MDTable.Constant,defaultVal);
  1132. defaultVal.BuildTables(md);
  1133. }
  1134. if (marshalInfo != null) {
  1135. md.AddToTable(MDTable.FieldMarshal,marshalInfo);
  1136. marshalInfo.BuildTables(md);
  1137. }
  1138. done = true;
  1139. }
  1140. internal void TypeSig(MemoryStream str)
  1141. {
  1142. pType.TypeSig(str);
  1143. }
  1144. internal sealed override uint Size(MetaData md)
  1145. {
  1146. return 4 + md.StringsIndexSize();
  1147. }
  1148. internal sealed override void Write(FileImage output)
  1149. {
  1150. output.Write(parMode);
  1151. output.Write(seqNo);
  1152. output.StringsIndex(nameIx);
  1153. }
  1154. internal sealed override uint GetCodedIx(CIx code)
  1155. {
  1156. switch (code) {
  1157. case (CIx.HasCustomAttr) : return 4;
  1158. case (CIx.HasConst) : return 1;
  1159. case (CIx.HasFieldMarshal) : return 1;
  1160. }
  1161. return 0;
  1162. }
  1163. }
  1164. /**************************************************************************/
  1165. public abstract class Signature : MetaDataElement {
  1166. protected uint sigIx;
  1167. internal Signature()
  1168. {
  1169. tabIx = MDTable.StandAloneSig;
  1170. }
  1171. internal sealed override uint Size(MetaData md)
  1172. {
  1173. return md.BlobIndexSize();
  1174. }
  1175. internal sealed override void Write(FileImage output)
  1176. {
  1177. output.BlobIndex(sigIx);
  1178. }
  1179. internal sealed override uint GetCodedIx(CIx code) { return (uint)tabIx; }
  1180. }
  1181. /**************************************************************************/
  1182. public class TypeSpec : MetaDataElement {
  1183. uint sigIx = 0;
  1184. internal TypeSpec(Type aType, MetaData md)
  1185. {
  1186. MemoryStream sig = new MemoryStream();
  1187. aType.TypeSig(sig);
  1188. sigIx = md.AddToBlobHeap(sig.ToArray());
  1189. tabIx = MDTable.TypeSpec;
  1190. }
  1191. internal sealed override uint GetCodedIx(CIx code)
  1192. {
  1193. switch (code) {
  1194. case (CIx.TypeDefOrRef) : return 2;
  1195. case (CIx.HasCustomAttr) : return 13;
  1196. case (CIx.MemberRefParent) : return 4;
  1197. }
  1198. return 0;
  1199. }
  1200. internal override uint Size(MetaData md)
  1201. {
  1202. return md.BlobIndexSize();
  1203. }
  1204. internal sealed override void Write(FileImage output)
  1205. {
  1206. //Console.WriteLine("Writing the blob index for a TypeSpec");
  1207. output.BlobIndex(sigIx);
  1208. }
  1209. }
  1210. /**************************************************************************/
  1211. /// <summary>
  1212. /// Base class for all IL types
  1213. /// </summary>
  1214. public abstract class Type : MetaDataElement {
  1215. protected byte typeIndex;
  1216. protected TypeSpec typeSpec;
  1217. internal Type(byte tyIx) { typeIndex = tyIx; }
  1218. internal byte GetTypeIndex() { return typeIndex; }
  1219. internal void SetTypeIndex (byte b) { typeIndex = b; }
  1220. internal virtual MetaDataElement GetTypeSpec(MetaData md)
  1221. {
  1222. if (typeSpec == null) {
  1223. typeSpec = new TypeSpec(this,md);
  1224. md.AddToTable(MDTable.TypeSpec,typeSpec);
  1225. }
  1226. return typeSpec;
  1227. }
  1228. internal virtual void TypeSig(MemoryStream str)
  1229. {
  1230. throw(new TypeSignatureException(this.GetType().AssemblyQualifiedName +
  1231. " doesn't have a type signature!!"));
  1232. }
  1233. }
  1234. public class ClassRefInst : Type {
  1235. private Type type;
  1236. private bool is_value;
  1237. public ClassRefInst (Type type, bool is_value) : base (PrimitiveType.Class.GetTypeIndex ())
  1238. {
  1239. this.type = type;
  1240. this.is_value = is_value;
  1241. if (is_value)
  1242. typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
  1243. tabIx = MDTable.TypeSpec;
  1244. }
  1245. internal sealed override void TypeSig(MemoryStream str)
  1246. {
  1247. type.TypeSig (str);
  1248. }
  1249. }
  1250. /**************************************************************************/
  1251. /// <summary>
  1252. /// The base descriptor for a class
  1253. /// </summary>
  1254. public abstract class Class : Type {
  1255. protected int row = 0;
  1256. public string name, nameSpace;
  1257. protected uint nameIx, nameSpaceIx;
  1258. protected MetaData _metaData;
  1259. internal Class(string nameSpaceName, string className, MetaData md)
  1260. : base(PrimitiveType.Class.GetTypeIndex ())
  1261. {
  1262. nameSpace = nameSpaceName;
  1263. name = className;
  1264. nameIx = md.AddToStringsHeap(name);
  1265. nameSpaceIx = md.AddToStringsHeap(nameSpace);
  1266. _metaData = md;
  1267. }
  1268. internal Class(uint nsIx, uint nIx) : base(PrimitiveType.Class.GetTypeIndex ())
  1269. {
  1270. nameSpaceIx = nsIx;
  1271. nameIx = nIx;
  1272. }
  1273. internal Class (byte typeIndex) : base (typeIndex)
  1274. {
  1275. nameSpace = "Should not be used";
  1276. name = "Should not be used";
  1277. }
  1278. internal virtual uint TypeDefOrRefToken() { return 0; }
  1279. internal virtual void MakeValueClass(ValueClass vClass)
  1280. {
  1281. typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
  1282. }
  1283. internal virtual string TypeName()
  1284. {
  1285. return (nameSpace + "." + name);
  1286. }
  1287. internal override MetaDataElement GetTypeSpec(MetaData md)
  1288. {
  1289. return this;
  1290. }
  1291. }
  1292. /**************************************************************************/
  1293. // This Class produces entries in the TypeDef table of the MetaData
  1294. // in the PE meta data.
  1295. // NOTE: Entry 0 in TypeDef table is always the pseudo class <module>
  1296. // which is the parent for functions and variables declared a module level
  1297. /// <summary>
  1298. /// The descriptor for a class defined in the IL (.class) in the current assembly/module
  1299. /// </summary>
  1300. ///
  1301. public class ClassDef : Class {
  1302. private static readonly byte ElementType_Class = 0x12;
  1303. Class superType;
  1304. ArrayList fields = new ArrayList();
  1305. ArrayList methods = new ArrayList();
  1306. ArrayList events;
  1307. ArrayList properties;
  1308. bool typeIndexChecked = true;
  1309. uint fieldIx = 0, methodIx = 0;
  1310. byte[] securityActions;
  1311. uint flags;
  1312. ClassLayout layout;
  1313. ClassDef parentClass;
  1314. MetaData metaData;
  1315. internal ClassDef(TypeAttr attrSet, string nsName, string name,
  1316. MetaData md) : base(nsName, name, md)
  1317. {
  1318. metaData = md;
  1319. if (! ((nsName == "" && name == "<Module>") || (nsName == "System" && name == "Object")) ) {
  1320. superType = metaData.mscorlib.GetSpecialSystemClass(PrimitiveType.Object);
  1321. }
  1322. flags = (uint)attrSet;
  1323. tabIx = MDTable.TypeDef;
  1324. }
  1325. internal void SetSuper(Class sClass)
  1326. {
  1327. superType = sClass;
  1328. if (! (sClass is GenericTypeInst))
  1329. typeIndexChecked = false;
  1330. }
  1331. internal override void MakeValueClass(ValueClass vClass)
  1332. {
  1333. if (vClass == ValueClass.Enum)
  1334. superType = metaData.mscorlib.EnumType();
  1335. else
  1336. superType = metaData.mscorlib.ValueType();
  1337. typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
  1338. }
  1339. public void SpecialNoSuper()
  1340. {
  1341. superType = null;
  1342. }
  1343. /// <summary>
  1344. /// Add an attribute to this class
  1345. /// </summary>
  1346. /// <param name="ta">the attribute to be added</param>
  1347. public void AddAttribute(TypeAttr ta)
  1348. {
  1349. flags |= (uint)ta;
  1350. }
  1351. /// <summary>
  1352. /// Add an interface that is implemented by this class
  1353. /// </summary>
  1354. /// <param name="iFace">the interface that is implemented</param>
  1355. public void AddImplementedInterface(Class iFace)
  1356. {
  1357. metaData.AddToTable(MDTable.InterfaceImpl,new InterfaceImpl(this,iFace));
  1358. }
  1359. /// <summary>
  1360. /// Add a named generic type parameter
  1361. /// </summary>
  1362. public GenericParameter AddGenericParameter (short index, string name)
  1363. {
  1364. return AddGenericParameter (index, name, 0);
  1365. }
  1366. /// <summary>
  1367. /// Add a named generic type parameter with attributes
  1368. /// </summary>
  1369. public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
  1370. {
  1371. GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
  1372. metaData.AddToTable (MDTable.GenericParam, gp);
  1373. return gp;
  1374. }
  1375. /// <summary>
  1376. /// Add a field to this class
  1377. /// </summary>
  1378. /// <param name="name">field name</param>
  1379. /// <param name="fType">field type</param>
  1380. /// <returns>a descriptor for this new field</returns>
  1381. public FieldDef AddField(string name, Type fType)
  1382. {
  1383. FieldDef field = new FieldDef(name,fType);
  1384. fields.Add(field);
  1385. return field;
  1386. }
  1387. /// <summary>
  1388. /// Add a field to this class
  1389. /// </summary>
  1390. /// <param name="fAtts">attributes for this field</param>
  1391. /// <param name="name">field name</param>
  1392. /// <param name="fType">field type</param>
  1393. /// <returns>a descriptor for this new field</returns>
  1394. public FieldDef AddField(FieldAttr fAtts, string name, Type fType)
  1395. {
  1396. FieldDef field = new FieldDef(fAtts,name,fType);
  1397. fields.Add(field);
  1398. return field;
  1399. }
  1400. public void SetFieldOrder (ArrayList fields)
  1401. {
  1402. this.fields = fields;
  1403. }
  1404. /// <summary>
  1405. /// Add a method to this class
  1406. /// </summary>
  1407. /// <param name="name">method name</param>
  1408. /// <param name="retType">return type</param>
  1409. /// <param name="pars">parameters</param>
  1410. /// <returns>a descriptor for this new method</returns>
  1411. public MethodDef AddMethod(string name, Type retType, Param[] pars)
  1412. {
  1413. return AddMethod (name, new Param (ParamAttr.Default, "", retType), pars);
  1414. }
  1415. public MethodDef AddMethod (string name, Param ret_param, Param [] pars)
  1416. {
  1417. // Console.WriteLine("Adding method " + name + " to class " + this.name);
  1418. MethodDef meth = new MethodDef(metaData,name, ret_param, pars);
  1419. methods.Add(meth);
  1420. return meth;
  1421. }
  1422. /// <summary>
  1423. /// Add a method to this class
  1424. /// </summary>
  1425. /// <param name="mAtts">attributes for this method</param>
  1426. /// <param name="iAtts">implementation attributes for this method</param>
  1427. /// <param name="name">method name</param>
  1428. /// <param name="retType">return type</param>
  1429. /// <param name="pars">parameters</param>
  1430. /// <returns>a descriptor for this new method</returns>
  1431. public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name,
  1432. Param ret_param, Param [] pars) {
  1433. // Console.WriteLine("Adding method " + name + " to class " + this.name);
  1434. MethodDef meth = new MethodDef (metaData, mAtts, iAtts, name, ret_param, pars);
  1435. methods.Add(meth);
  1436. return meth;
  1437. }
  1438. /// <summary>
  1439. /// Add an event to this class
  1440. /// </summary>
  1441. /// <param name="name">event name</param>
  1442. /// <param name="eType">event type</param>
  1443. /// <returns>a descriptor for this new event</returns>
  1444. public Event AddEvent(string name, Type eType)
  1445. {
  1446. Event e = new Event(name,eType,this);
  1447. if (events == null) events = new ArrayList();
  1448. events.Add(e);
  1449. return e;
  1450. }
  1451. /// <summary>
  1452. /// Add a property to this class
  1453. /// </summary>
  1454. /// <param name="name">property name</param>
  1455. /// <param name="propType">property type</param>
  1456. /// <returns>a descriptor for this new property</returns>
  1457. public Property AddProperty(string name, Type retType, Type[] pars)
  1458. {
  1459. Property p = new Property(name, retType, pars, this);
  1460. if (properties == null) properties = new ArrayList();
  1461. properties.Add(p);
  1462. return p;
  1463. }
  1464. /// <summary>
  1465. /// Add a nested class to this class
  1466. /// </summary>
  1467. /// <param name="attrSet">attributes for this nested class</param>
  1468. /// <param name="nsName">nested name space name</param>
  1469. /// <param name="name">nested class name</param>
  1470. /// <returns>a descriptor for this new nested class</returns>
  1471. public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
  1472. string name) {
  1473. ClassDef nClass = new ClassDef(attrSet,"",name,metaData);
  1474. metaData.AddToTable(MDTable.TypeDef,nClass);
  1475. metaData.AddToTable(MDTable.NestedClass,new MapElem(nClass,Row,MDTable.TypeDef));
  1476. nClass.parentClass = this;
  1477. return (nClass);
  1478. }
  1479. public static bool IsValueType (Class type)
  1480. {
  1481. return IsValueType (type.nameSpace, type.name);
  1482. }
  1483. public static bool IsEnum (Class type)
  1484. {
  1485. return IsEnum (type.nameSpace, type.name);
  1486. }
  1487. public static bool IsValueType (string nsName, string name)
  1488. {
  1489. return (nsName == "System" && name == "ValueType");
  1490. }
  1491. public static bool IsEnum (string nsName, string name)
  1492. {
  1493. return (nsName == "System" && name == "Enum");
  1494. }
  1495. /// <summary>
  1496. /// Add a nested class to this class
  1497. /// </summary>
  1498. /// <param name="attrSet">attributes for this nested class</param>
  1499. /// <param name="nsName">nested name space name</param>
  1500. /// <param name="name">nested class name</param>
  1501. /// <param name="sType">super type of this nested class</param>
  1502. /// <returns>a descriptor for this new nested class</returns>
  1503. public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
  1504. string name, Class sType) {
  1505. ClassDef nClass = AddNestedClass (attrSet, nsName, name);
  1506. nClass.SetSuper(sType);
  1507. if (ClassDef.IsValueType (sType))
  1508. nClass.MakeValueClass (ValueClass.ValueType);
  1509. else
  1510. if (ClassDef.IsEnum (sType))
  1511. nClass.MakeValueClass (ValueClass.Enum);
  1512. if (ClassDef.IsValueType (sType) || ClassDef.IsEnum (sType))
  1513. nClass.SetTypeIndex (PrimitiveType.ValueType.GetTypeIndex ());
  1514. nClass.typeIndexChecked = true;
  1515. return (nClass);
  1516. }
  1517. /// <summary>
  1518. /// Add layout information for this class. This class must have the
  1519. /// sequential or explicit attribute.
  1520. /// </summary>
  1521. /// <param name="packSize">packing size (.pack)</param>
  1522. /// <param name="classSize">class size (.size)</param>
  1523. public void AddLayoutInfo (int packSize, int classSize)
  1524. {
  1525. layout = new ClassLayout(packSize,classSize,this);
  1526. }
  1527. /// <summary>
  1528. /// Use a method as the implementation for another method (.override)
  1529. /// </summary>
  1530. /// <param name="decl">the method to be overridden</param>
  1531. /// <param name="body">the implementation to be used</param>
  1532. public void AddMethodOverride(Method decl, Method body)
  1533. {
  1534. metaData.AddToTable(MDTable.MethodImpl,new MethodImpl(this,decl,body));
  1535. }
  1536. /// <summary>
  1537. /// Add security to this class NOT YET IMPLEMENTED
  1538. /// </summary>
  1539. /// <param name="permissionSet"></param>
  1540. public void AddSecurity(byte[] permissionSet)
  1541. {
  1542. throw(new NotYetImplementedException("Class security "));
  1543. //flags |= HasSecurity;
  1544. // securityActions = permissionSet;
  1545. }
  1546. //public void AddLineInfo(int row, int col) { }
  1547. internal void CheckTypeIndex()
  1548. {
  1549. if (typeIndexChecked) return;
  1550. if (superType is ClassDef)
  1551. ((ClassDef)superType).CheckTypeIndex();
  1552. typeIndex = superType.GetTypeIndex();
  1553. typeIndexChecked = true;
  1554. }
  1555. internal sealed override void BuildTables(MetaData md)
  1556. {
  1557. if (done) return;
  1558. if ((flags & (uint)TypeAttr.Interface) != 0) { superType = null; }
  1559. // Console.WriteLine("Building tables for " + name);
  1560. if (layout != null) md.AddToTable(MDTable.ClassLayout,layout);
  1561. // Console.WriteLine("adding methods " + methods.Count);
  1562. methodIx = md.TableIndex(MDTable.Method);
  1563. for (int i=0; i < methods.Count; i++) {
  1564. md.AddToTable(MDTable.Method,(MetaDataElement)methods[i]);
  1565. ((MethodDef)methods[i]).BuildTables(md);
  1566. }
  1567. // Console.WriteLine("adding fields");
  1568. fieldIx = md.TableIndex(MDTable.Field);
  1569. for (int i=0; i < fields.Count; i++) {
  1570. md.AddToTable(MDTable.Field,(MetaDataElement)fields[i]);
  1571. ((FieldDef)fields[i]).BuildTables(md);
  1572. }
  1573. // Console.WriteLine("adding events and properties");
  1574. if (events != null) {
  1575. for (int i=0; i < events.Count; i++) {
  1576. md.AddToTable(MDTable.Event,(Event)events[i]);
  1577. ((Event)events[i]).BuildTables(md);
  1578. }
  1579. md.AddToTable(MDTable.EventMap,
  1580. new MapElem(this,((Event)events[0]).Row,MDTable.Event));
  1581. }
  1582. if (properties != null) {
  1583. for (int i=0; i < properties.Count; i++) {
  1584. md.AddToTable(MDTable.Property,(Property)properties[i]);
  1585. ((Property)properties[i]).BuildTables(md);
  1586. }
  1587. md.AddToTable(MDTable.PropertyMap,new MapElem(this,
  1588. ((Property)properties[0]).Row,MDTable.Property));
  1589. }
  1590. // Console.WriteLine("End of building tables");
  1591. done = true;
  1592. }
  1593. internal sealed override uint Size(MetaData md)
  1594. {
  1595. return 4 + 2 * md.StringsIndexSize() +
  1596. md.CodedIndexSize(CIx.TypeDefOrRef) +
  1597. md.TableIndexSize(MDTable.Field) +
  1598. md.TableIndexSize(MDTable.Method);
  1599. }
  1600. internal sealed override void Write(FileImage output)
  1601. {
  1602. output.Write(flags);
  1603. output.StringsIndex(nameIx);
  1604. output.StringsIndex(nameSpaceIx);
  1605. //if (superType != null)
  1606. // Console.WriteLine("getting coded index for superType of " + name + " = " + superType.GetCodedIx(CIx.TypeDefOrRef));
  1607. output.WriteCodedIndex(CIx.TypeDefOrRef,superType);
  1608. output.WriteIndex(MDTable.Field,fieldIx);
  1609. output.WriteIndex(MDTable.Method,methodIx);
  1610. }
  1611. internal sealed override uint TypeDefOrRefToken()
  1612. {
  1613. uint cIx = Row;
  1614. cIx = cIx << 2;
  1615. return cIx;
  1616. }
  1617. internal sealed override void TypeSig(MemoryStream sig)
  1618. {
  1619. if (!typeIndexChecked) CheckTypeIndex();
  1620. sig.WriteByte(GetTypeIndex());
  1621. MetaData.CompressNum(TypeDefOrRefToken(),sig);
  1622. }
  1623. internal sealed override uint GetCodedIx(CIx code)
  1624. {
  1625. switch (code) {
  1626. case (CIx.TypeDefOrRef) : return 0;
  1627. case (CIx.HasCustomAttr) : return 3;
  1628. case (CIx.HasDeclSecurity) : return 0;
  1629. case (CIx.TypeOrMethodDef) : return 0;
  1630. }
  1631. return 0;
  1632. }
  1633. }
  1634. /**************************************************************************/
  1635. /// <summary>
  1636. /// Descriptor for a class/interface declared in another module of THIS
  1637. /// assembly, or in another assembly.
  1638. /// </summary>
  1639. public class ClassRef : Class, IExternRef, IResolutionScope {
  1640. protected IResolutionScope parent;
  1641. ExternClass externClass;
  1642. protected MetaData metaData;
  1643. internal ClassRef(string nsName, string name, MetaData md) : base(nsName, name, md)
  1644. {
  1645. metaData = md;
  1646. tabIx = MDTable.TypeRef;
  1647. }
  1648. /// <summary>
  1649. /// Add a method to this class
  1650. /// </summary>
  1651. /// <param name="name">method name</param>
  1652. /// <param name="retType">return type</param>
  1653. /// <param name="pars">parameter types</param>
  1654. /// <returns>a descriptor for this method</returns>
  1655. public MethodRef AddMethod(string name, Type retType, Type[] pars)
  1656. {
  1657. return AddMethod (name, retType, pars, 0);
  1658. }
  1659. /// <summary>
  1660. /// Add a method to this class
  1661. /// </summary>
  1662. /// <param name="name">method name</param>
  1663. /// <param name="retType">return type</param>
  1664. /// <param name="pars">parameter types</param>
  1665. /// <param name="gen_param_count">num of generic parameters</param>
  1666. /// <returns>a descriptor for this method</returns>
  1667. public MethodRef AddMethod (string name, Type retType, Type[] pars, int gen_param_count)
  1668. {
  1669. MethodRef meth = new MethodRef (this, name, retType, pars, false, null, gen_param_count);
  1670. metaData.AddToTable(MDTable.MemberRef,meth);
  1671. return meth;
  1672. }
  1673. /// <summary>
  1674. /// Add a method to this class
  1675. /// </summary>
  1676. /// <param name="name">method name</param>
  1677. /// <param name="retType">return type</param>
  1678. /// <param name="pars">parameter types</param>
  1679. /// <returns>a descriptor for this method</returns>
  1680. public MethodRef AddVarArgMethod(string name, Type retType,
  1681. Type[] pars, Type[] optPars)
  1682. {
  1683. MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
  1684. metaData.AddToTable(MDTable.MemberRef,meth);
  1685. return meth;
  1686. }
  1687. /// <summary>
  1688. /// Add a field to this class
  1689. /// </summary>
  1690. /// <param name="name">field name</param>
  1691. /// <param name="fType">field type</param>
  1692. /// <returns>a descriptor for this field</returns>
  1693. public FieldRef AddField(string name, Type fType)
  1694. {
  1695. FieldRef field = new FieldRef(this,name,fType);
  1696. metaData.AddToTable(MDTable.MemberRef,field);
  1697. return field;
  1698. }
  1699. public ClassRef AddClass (string nsName, string name)
  1700. {
  1701. ClassRef aClass = new ClassRef(nsName,name,metaData);
  1702. metaData.AddToTable(MDTable.TypeRef,aClass);
  1703. aClass.SetParent(this);
  1704. return aClass;
  1705. }
  1706. public ClassRef AddValueClass (string nsName, string name)
  1707. {
  1708. ClassRef aClass = AddClass (nsName, name);
  1709. aClass.MakeValueClass (ValueClass.ValueType);
  1710. return aClass;
  1711. }
  1712. internal void SetParent(IResolutionScope par)
  1713. {
  1714. parent = par;
  1715. }
  1716. internal override string TypeName()
  1717. {
  1718. if ((parent != null) && (parent is AssemblyRef))
  1719. return (nameSpace + "." + name + ", " + ((AssemblyRef)parent).TypeName());
  1720. else
  1721. return (nameSpace + name);
  1722. }
  1723. internal sealed override uint Size(MetaData md)
  1724. {
  1725. return md.CodedIndexSize(CIx.ResolutionScope) + 2 *
  1726. md.StringsIndexSize();
  1727. }
  1728. internal sealed override void Write(FileImage output)
  1729. {
  1730. output.WriteCodedIndex(CIx.ResolutionScope,(MetaDataElement) parent);
  1731. output.StringsIndex(nameIx);
  1732. output.StringsIndex(nameSpaceIx);
  1733. }
  1734. internal override sealed uint TypeDefOrRefToken()
  1735. {
  1736. uint cIx = Row;
  1737. cIx = (cIx << 2) | 0x1;
  1738. return cIx;
  1739. }
  1740. internal override void TypeSig(MemoryStream sig)
  1741. {
  1742. sig.WriteByte(GetTypeIndex());
  1743. MetaData.CompressNum(TypeDefOrRefToken(),sig);
  1744. }
  1745. internal sealed override uint GetCodedIx(CIx code)
  1746. {
  1747. switch (code) {
  1748. case (CIx.TypeDefOrRef) : return 1;
  1749. case (CIx.HasCustomAttr) : return 2;
  1750. case (CIx.MemberRefParent) : return 1;
  1751. case (CIx.ResolutionScope) : return 3;
  1752. }
  1753. return 0;
  1754. }
  1755. }
  1756. /**************************************************************************/
  1757. public class ExternClassRef : ClassRef {
  1758. ExternClass externClass;
  1759. internal ExternClassRef(TypeAttr attrs, string nsName, string name,
  1760. FileRef declFile, MetaData md) : base(nsName,name,md)
  1761. {
  1762. externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declFile);
  1763. metaData.AddToTable(MDTable.ExportedType,externClass);
  1764. }
  1765. internal ExternClassRef(string name, MetaData md) : base(null,name,md)
  1766. {
  1767. }
  1768. public ClassRef AddNestedClass(TypeAttr attrs, string name)
  1769. {
  1770. ExternClassRef nestedClass = new ExternClassRef(name,metaData);
  1771. externClass = new ExternClass(attrs,0,nameIx,this.externClass);
  1772. metaData.AddToTable(MDTable.ExportedType,externClass);
  1773. return nestedClass;
  1774. }
  1775. }
  1776. /**************************************************************************/
  1777. /// <summary>
  1778. /// Descriptor for a class defined in another module of THIS assembly
  1779. /// and exported (.class extern)
  1780. /// </summary>
  1781. internal class ExternClass : Class {
  1782. MetaDataElement parent;
  1783. uint flags;
  1784. internal ExternClass(TypeAttr attr, uint nsIx, uint nIx,
  1785. MetaDataElement paren) : base(nsIx,nIx)
  1786. {
  1787. flags = (uint)attr;
  1788. parent = paren;
  1789. tabIx = MDTable.ExportedType;
  1790. }
  1791. internal sealed override uint Size(MetaData md)
  1792. {
  1793. return 8 + 2* md.StringsIndexSize() + md.CodedIndexSize(CIx.Implementation);
  1794. }
  1795. internal sealed override void Write(FileImage output)
  1796. {
  1797. output.Write(flags);
  1798. output.Write(0);
  1799. output.StringsIndex(nameIx);
  1800. output.StringsIndex(nameSpaceIx);
  1801. output.WriteCodedIndex(CIx.Implementation,parent);
  1802. }
  1803. internal sealed override uint GetCodedIx(CIx code)
  1804. {
  1805. switch (code) {
  1806. case (CIx.HasCustomAttr) : return 17;
  1807. case (CIx.Implementation) : return 2;
  1808. }
  1809. return 0;
  1810. }
  1811. }
  1812. public class GenParam : Class {
  1813. private int index;
  1814. private string param_name;
  1815. private uint sigIx = 0;
  1816. public GenParam (int index, string name, GenParamType ptype) : base ((byte) ptype)
  1817. {
  1818. this.index = index;
  1819. this.param_name = name;
  1820. tabIx = MDTable.TypeSpec;
  1821. }
  1822. public int Index {
  1823. get { return index; }
  1824. set { index = value; }
  1825. }
  1826. public string Name {
  1827. get { return param_name; }
  1828. set { param_name = value; }
  1829. }
  1830. public GenParamType Type {
  1831. get { return (GenParamType) GetTypeIndex (); }
  1832. }
  1833. internal sealed override void BuildTables (MetaData md)
  1834. {
  1835. if (done)
  1836. return;
  1837. MemoryStream str = new MemoryStream ();
  1838. TypeSig (str);
  1839. sigIx = md.AddToBlobHeap (str.ToArray ());
  1840. done = true;
  1841. }
  1842. internal sealed override void TypeSig(MemoryStream str)
  1843. {
  1844. if (index < 0)
  1845. throw new PEFileException (String.Format ("Unresolved {0} - {1}", (GenParamType) GetTypeIndex (), param_name));
  1846. str.WriteByte(typeIndex);
  1847. MetaData.CompressNum ((uint) index, str);
  1848. }
  1849. internal override uint Size(MetaData md)
  1850. {
  1851. return md.BlobIndexSize();
  1852. }
  1853. internal sealed override void Write (FileImage output)
  1854. {
  1855. output.BlobIndex (sigIx);
  1856. }
  1857. internal sealed override uint GetCodedIx(CIx code)
  1858. {
  1859. switch (code) {
  1860. case (CIx.TypeDefOrRef) : return 2;
  1861. case (CIx.HasCustomAttr) : return 13;
  1862. case (CIx.MemberRefParent) : return 4;
  1863. }
  1864. return 0;
  1865. }
  1866. }
  1867. public class GenericTypeInst : Class {
  1868. private Type gen_type;
  1869. private Type[] gen_param;
  1870. bool inTable = false;
  1871. uint sigIx = 0;
  1872. public GenericTypeInst (Type gen_type, Type[] gen_param)
  1873. : base ((byte) PrimitiveType.GenericInst.GetTypeIndex ())
  1874. {
  1875. this.gen_type = gen_type;
  1876. this.gen_param = gen_param;
  1877. tabIx = MDTable.TypeSpec;
  1878. }
  1879. internal override MetaDataElement GetTypeSpec (MetaData md)
  1880. {
  1881. if (!inTable) {
  1882. md.AddToTable (MDTable.TypeSpec, this);
  1883. inTable = true;
  1884. }
  1885. return this;
  1886. }
  1887. internal sealed override void TypeSig(MemoryStream str)
  1888. {
  1889. str.WriteByte(typeIndex);
  1890. gen_type.TypeSig (str);
  1891. MetaData.CompressNum ((uint) gen_param.Length, str);
  1892. foreach (Type param in gen_param)
  1893. param.TypeSig (str);
  1894. }
  1895. internal sealed override void BuildTables (MetaData md)
  1896. {
  1897. if (done)
  1898. return;
  1899. MemoryStream str = new MemoryStream ();
  1900. TypeSig (str);
  1901. sigIx = md.AddToBlobHeap (str.ToArray ());
  1902. done = true;
  1903. }
  1904. internal sealed override uint Size (MetaData md)
  1905. {
  1906. return md.BlobIndexSize ();
  1907. }
  1908. internal sealed override void Write (FileImage output)
  1909. {
  1910. output.BlobIndex (sigIx);
  1911. }
  1912. internal sealed override uint GetCodedIx (CIx code)
  1913. {
  1914. switch (code) {
  1915. case (CIx.TypeDefOrRef): return 2;
  1916. case (CIx.MemberRefParent): return 4;
  1917. case (CIx.HasCustomAttr): return 13;
  1918. }
  1919. return 0;
  1920. }
  1921. }
  1922. public class GenericMethodSig {
  1923. private Type[] gen_param;
  1924. private bool done;
  1925. private uint sigIx = 0;
  1926. public GenericMethodSig (Type[] gen_param)
  1927. {
  1928. this.gen_param = gen_param;
  1929. done = false;
  1930. }
  1931. internal void TypeSig (MemoryStream str)
  1932. {
  1933. str.WriteByte (0x0A); /* GENERIC_INST */
  1934. MetaData.CompressNum ((uint) gen_param.Length, str);
  1935. foreach (Type param in gen_param)
  1936. param.TypeSig (str);
  1937. }
  1938. internal uint GetSigIx (MetaData md)
  1939. {
  1940. if (done)
  1941. return sigIx;
  1942. MemoryStream sig = new MemoryStream();
  1943. TypeSig (sig);
  1944. sigIx = md.AddToBlobHeap (sig.ToArray());
  1945. done = true;
  1946. return sigIx;
  1947. }
  1948. }
  1949. public class Sentinel : Type {
  1950. public Sentinel () : base (0x41) { }
  1951. internal sealed override void TypeSig(MemoryStream str)
  1952. {
  1953. str.WriteByte(typeIndex);
  1954. }
  1955. }
  1956. /**************************************************************************/
  1957. /// <summary>
  1958. /// Descriptor for a FunctionPointer type
  1959. /// </summary>
  1960. ///
  1961. public class MethPtrType : Type {
  1962. bool varArgMeth;
  1963. Type retType;
  1964. Type [] parList;
  1965. Type [] optParList;
  1966. CallConv callConv;
  1967. uint numPars;
  1968. uint numOptPars;
  1969. uint sigIx = 0;
  1970. /// <summary>
  1971. /// Create a new function pointer type
  1972. /// </summary>
  1973. /// <param name="meth">the function to be referenced</param>
  1974. public MethPtrType (CallConv callconv, Type retType, Type[] pars,
  1975. bool varArgMeth, Type[] optPars) : base(0x1B)
  1976. {
  1977. this.retType = retType;
  1978. callConv = callconv;
  1979. parList = pars;
  1980. this.varArgMeth = varArgMeth;
  1981. if (parList != null) numPars = (uint)parList.Length;
  1982. if (varArgMeth) {
  1983. optParList = optPars;
  1984. if (optParList != null) numOptPars = (uint)optParList.Length;
  1985. callConv |= CallConv.Vararg;
  1986. }
  1987. tabIx = MDTable.TypeSpec;
  1988. }
  1989. internal sealed override void TypeSig(MemoryStream sig)
  1990. {
  1991. sig.WriteByte(typeIndex);
  1992. // Bootlegged from method ref
  1993. sig.WriteByte((byte)callConv);
  1994. MetaData.CompressNum (numPars + numOptPars, sig);
  1995. retType.TypeSig (sig);
  1996. for (int i=0; i < numPars; i++) {
  1997. parList[i].TypeSig (sig);
  1998. }
  1999. if (varArgMeth) {
  2000. sig.WriteByte (0x41); // Write the sentinel
  2001. for (int i=0; i < numOptPars; i++) {
  2002. optParList[i].TypeSig (sig);
  2003. }
  2004. }
  2005. }
  2006. internal sealed override void BuildTables(MetaData md)
  2007. {
  2008. if (done) return;
  2009. MemoryStream sig = new MemoryStream();
  2010. TypeSig(sig);
  2011. sigIx = md.AddToBlobHeap(sig.ToArray());
  2012. done = true;
  2013. }
  2014. internal sealed override uint Size(MetaData md)
  2015. {
  2016. return md.BlobIndexSize();
  2017. }
  2018. internal sealed override void Write(FileImage output)
  2019. {
  2020. output.BlobIndex(sigIx);
  2021. }
  2022. internal sealed override uint GetCodedIx(CIx code) { return 0x1B; }
  2023. }
  2024. #region Array Types
  2025. /* Classes for Arrays */
  2026. /// <summary>
  2027. /// The IL Array type
  2028. /// </summary>
  2029. public abstract class Array : Type {
  2030. protected Type elemType;
  2031. protected MetaData metaData;
  2032. protected string cnameSpace, cname;
  2033. internal Array(Type eType, byte TypeId) : base(TypeId)
  2034. {
  2035. elemType = eType;
  2036. tabIx = MDTable.TypeSpec;
  2037. }
  2038. }
  2039. /// <summary>
  2040. /// Single dimensional array with zero lower bound
  2041. /// </summary>
  2042. public class ZeroBasedArray : Array {
  2043. /// <summary>
  2044. /// Create a new array - elementType[]
  2045. /// </summary>
  2046. /// <param name="elementType">the type of the array elements</param>
  2047. public ZeroBasedArray(Type elementType) : base (elementType, PrimitiveType.SZArray.GetTypeIndex ()) { }
  2048. internal sealed override void TypeSig(MemoryStream str)
  2049. {
  2050. str.WriteByte(typeIndex);
  2051. elemType.TypeSig(str);
  2052. }
  2053. }
  2054. /// <summary>
  2055. /// Multi dimensional array with explicit bounds
  2056. /// </summary>
  2057. public class BoundArray : Array {
  2058. int[] lowerBounds;
  2059. int[] sizes;
  2060. uint numDims;
  2061. /// <summary>
  2062. /// Create a new multi dimensional array type
  2063. /// eg. elemType[1..5,3..10,5,,] would be
  2064. /// new BoundArray(elemType,5,[1,3,0],[5,10,4])
  2065. /// </summary>
  2066. /// <param name="elementType">the type of the elements</param>
  2067. /// <param name="dimensions">the number of dimensions</param>
  2068. /// <param name="loBounds">lower bounds of dimensions</param>
  2069. /// <param name="sizes">sizes for the dimensions</param>
  2070. public BoundArray(Type elementType, uint dimensions, int[] loBounds,
  2071. int[] sizes) : base (elementType,0x14)
  2072. {
  2073. numDims = dimensions;
  2074. lowerBounds = loBounds;
  2075. this.sizes = sizes;
  2076. }
  2077. /// <summary>
  2078. /// Create a new multi dimensional array type
  2079. /// eg. elemType[5,10,20] would be new BoundArray(elemType,3,[5,10,20])
  2080. /// </summary>
  2081. /// <param name="elementType">the type of the elements</param>
  2082. /// <param name="dimensions">the number of dimensions</param>
  2083. /// <param name="size">the sizes of the dimensions</param>
  2084. public BoundArray(Type elementType, uint dimensions, int[] size)
  2085. : base (elementType,0x14)
  2086. {
  2087. numDims = dimensions;
  2088. sizes = size;
  2089. }
  2090. /// <summary>
  2091. /// Create a new multi dimensional array type
  2092. /// eg. elemType[,,] would be new BoundArray(elemType,3)
  2093. /// </summary>
  2094. /// <param name="elementType">the type of the elements</param>
  2095. /// <param name="dimensions">the number of dimensions</param>
  2096. public BoundArray(Type elementType, uint dimensions)
  2097. : base (elementType,0x14)
  2098. {
  2099. numDims = dimensions;
  2100. }
  2101. internal sealed override void TypeSig(MemoryStream str)
  2102. {
  2103. str.WriteByte(typeIndex);
  2104. elemType.TypeSig(str);
  2105. MetaData.CompressNum(numDims,str);
  2106. if ((sizes != null) && (sizes.Length > 0)) {
  2107. MetaData.CompressNum((uint)sizes.Length,str);
  2108. for (int i=0; i < sizes.Length; i++) {
  2109. MetaData.CompressNum((uint)sizes[i],str);
  2110. }
  2111. } else str.WriteByte(0);
  2112. if ((lowerBounds != null) && (lowerBounds.Length > 0)) {
  2113. MetaData.CompressNum((uint)lowerBounds.Length,str);
  2114. for (int i=0; i < lowerBounds.Length; i++) {
  2115. CompressSignedNum (lowerBounds[i],str);
  2116. }
  2117. } else str.WriteByte(0);
  2118. }
  2119. private void CompressSignedNum (int val, MemoryStream str)
  2120. {
  2121. uint uval = (uint) val;
  2122. byte sign = 0;
  2123. if (val < 0) {
  2124. val = -val;
  2125. sign = 1;
  2126. }
  2127. /* Map the signed number to an unsigned number in two ways.
  2128. fval: left-rotated 2's complement representation
  2129. sval: map the signed number to unsigned as follows: 0 -> 0, -1 -> 1, 1 -> 2, -2 -> 3, 2 -> 4, ....
  2130. the mapping is: x -> 2*|x| - signbit(x)
  2131. */
  2132. uint fval = (uval << 1) | sign;
  2133. int sval = (val << 1) - sign;
  2134. /* An overly clever transformation:
  2135. a. sval is used to determine the number of bytes in the compressed representation.
  2136. b. fval is truncated to the appropriate number of bits and output using the
  2137. normal unsigned-int compressor.
  2138. However, or certain values, the truncated fval doesn't carry enough information to round trip.
  2139. (fval & 0x3FFF) <= 0x7F => compressor emits 1 byte, not 2 => there is aliasing of values
  2140. So, we use full 4 bytes to encode such values.
  2141. LAMESPEC: The Microsoft implementation doesn't appear to handle this subtle case.
  2142. e.g., it ends up encoding -8192 as the byte 0x01, which decodes to -64
  2143. */
  2144. if (sval <= 0x7F)
  2145. MetaData.CompressNum (fval & 0x7F, str);
  2146. else if (sval <= 0x3FFF && (fval & 0x3FFF) > 0x7F)
  2147. MetaData.CompressNum (fval & 0x3FFF, str);
  2148. else if (sval <= 0x1FFFFFFF && (fval & 0x1FFFFFFF) > 0x3FFF)
  2149. MetaData.CompressNum (fval & 0x1FFFFFFF, str);
  2150. else
  2151. /* FIXME: number cannot be represented. Report a warning. */
  2152. // throw new Exception ("cannot represent signed value" + -val);
  2153. MetaData.CompressNum (fval, str);
  2154. }
  2155. }
  2156. #endregion
  2157. /* Empty interface for grouping TypeRef's possible ResolutionScope
  2158. namely : Module, ModuleRef, AssemblyRef and TypeRef */
  2159. public interface IResolutionScope {
  2160. }
  2161. /**************************************************************************/
  2162. /// <summary>
  2163. /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)
  2164. /// </summary>
  2165. public abstract class ResolutionScope : MetaDataElement, IResolutionScope {
  2166. protected uint nameIx = 0;
  2167. protected MetaData metaData;
  2168. protected string name;
  2169. internal ResolutionScope(string name, MetaData md)
  2170. {
  2171. metaData = md;
  2172. this.name = name;
  2173. nameIx = md.AddToStringsHeap(name);
  2174. }
  2175. internal string GetName() { return name; }
  2176. }
  2177. /**************************************************************************/
  2178. /// <summary>
  2179. /// Descriptor for THIS assembly (.assembly)
  2180. /// </summary>
  2181. public class Assembly : ResolutionScope {
  2182. ushort majorVer, minorVer, buildNo, revisionNo;
  2183. uint flags;
  2184. uint hashAlgId;
  2185. uint keyIx = 0, cultIx = 0;
  2186. bool hasPublicKey = false;
  2187. internal Assembly(string name, MetaData md) : base(name,md)
  2188. {
  2189. tabIx = MDTable.Assembly;
  2190. }
  2191. /// <summary>
  2192. /// Add details about THIS assembly
  2193. /// </summary>
  2194. /// <param name="majVer">Major Version</param>
  2195. /// <param name="minVer">Minor Version</param>
  2196. /// <param name="bldNo">Build Number</param>
  2197. /// <param name="revNo">Revision Number</param>
  2198. /// <param name="key">Hash Key</param>
  2199. /// <param name="hash">Hash Algorithm</param>
  2200. /// <param name="cult">Culture</param>
  2201. public void AddAssemblyInfo(int majVer, int minVer, int bldNo, int revNo,
  2202. byte[] key, uint hash, string cult)
  2203. {
  2204. majorVer = (ushort)majVer;
  2205. minorVer = (ushort)minVer;
  2206. buildNo = (ushort)bldNo;
  2207. revisionNo = (ushort)revNo;
  2208. hashAlgId = hash;
  2209. hasPublicKey = (key != null);
  2210. keyIx = metaData.AddToBlobHeap(key);
  2211. cultIx = metaData.AddToStringsHeap(cult);
  2212. }
  2213. /// <summary>
  2214. /// Add an attribute to THIS assembly
  2215. /// </summary>
  2216. /// <param name="aa">assembly attribute</param>
  2217. public void AddAssemblyAttr(AssemAttr aa)
  2218. {
  2219. flags |= (uint)aa;
  2220. }
  2221. internal sealed override uint Size(MetaData md)
  2222. {
  2223. return 16 + md.BlobIndexSize() + 2 * md.StringsIndexSize();
  2224. }
  2225. internal sealed override void Write(FileImage output)
  2226. {
  2227. // Console.WriteLine("Writing assembly element with nameIx of " + nameIx + " at file offset " + output.Seek(0,SeekOrigin.Current));
  2228. output.Write((uint)hashAlgId);
  2229. output.Write(majorVer);
  2230. output.Write(minorVer);
  2231. output.Write(buildNo);
  2232. output.Write(revisionNo);
  2233. output.Write(flags);
  2234. output.BlobIndex(keyIx);
  2235. output.StringsIndex(nameIx);
  2236. output.StringsIndex(cultIx);
  2237. }
  2238. internal sealed override uint GetCodedIx(CIx code)
  2239. {
  2240. switch (code) {
  2241. case (CIx.HasCustomAttr) : return 14;
  2242. case (CIx.HasDeclSecurity) : return 2;
  2243. }
  2244. return 0;
  2245. }
  2246. internal bool HasPublicKey {
  2247. get { return hasPublicKey; }
  2248. }
  2249. }
  2250. /**************************************************************************/
  2251. /// <summary>
  2252. /// Descriptor for THIS module
  2253. /// </summary>
  2254. public class Module : ResolutionScope, IExternRef {
  2255. Guid mvid;
  2256. uint mvidIx = 0;
  2257. internal Module(string name, MetaData md) : base(name,md)
  2258. {
  2259. mvid = Guid.NewGuid();
  2260. mvidIx = md.AddToGUIDHeap(mvid);
  2261. tabIx = MDTable.Module;
  2262. }
  2263. public Guid Guid {
  2264. get { return mvid; }
  2265. }
  2266. public ClassRef AddClass(string nsName, string name)
  2267. {
  2268. ClassRef aClass = new ClassRef (nsName, name, metaData);
  2269. metaData.AddToTable (MDTable.TypeRef, aClass);
  2270. aClass.SetParent (this);
  2271. return aClass;
  2272. }
  2273. public ClassRef AddValueClass(string nsName, string name)
  2274. {
  2275. ClassRef aClass = AddClass (nsName, name);
  2276. aClass.MakeValueClass (ValueClass.ValueType);
  2277. return aClass;
  2278. }
  2279. internal sealed override uint Size(MetaData md)
  2280. {
  2281. return 2 + md.StringsIndexSize() + 3 * md.GUIDIndexSize();
  2282. }
  2283. internal sealed override void Write(FileImage output)
  2284. {
  2285. output.Write((short)0);
  2286. output.StringsIndex(nameIx);
  2287. output.GUIDIndex(mvidIx);
  2288. output.GUIDIndex(0);
  2289. output.GUIDIndex(0);
  2290. }
  2291. internal sealed override uint GetCodedIx(CIx code)
  2292. {
  2293. switch (code) {
  2294. case (CIx.HasCustomAttr) : return 7;
  2295. case (CIx.ResolutionScope) : return 0;
  2296. }
  2297. return 0;
  2298. }
  2299. }
  2300. /**************************************************************************/
  2301. /// <summary>
  2302. /// Descriptor for another module in THIS assembly
  2303. /// </summary>
  2304. public class ModuleRef : ResolutionScope, IExternRef {
  2305. internal ModuleRef(MetaData md, string name) : base(name,md)
  2306. {
  2307. tabIx = MDTable.ModuleRef;
  2308. }
  2309. /// <summary>
  2310. /// Add a class to this external module. This is a class declared in
  2311. /// another module of THIS assembly.
  2312. /// </summary>
  2313. /// <param name="nsName">name space name</param>
  2314. /// <param name="name">class name</param>
  2315. /// <returns>a descriptor for this class in another module</returns>
  2316. public ClassRef AddClass(string nsName, string name)
  2317. {
  2318. ClassRef aClass = new ClassRef(nsName,name,metaData);
  2319. metaData.AddToTable(MDTable.TypeRef,aClass);
  2320. aClass.SetParent(this);
  2321. return aClass;
  2322. }
  2323. /// <summary>
  2324. /// Make a file descriptor to correspond to this module. The file
  2325. /// descriptor will have the same name as the module descriptor
  2326. /// </summary>
  2327. /// <param name="hashBytes">the hash of the file</param>
  2328. /// <param name="hasMetaData">the file contains metadata</param>
  2329. /// <param name="entryPoint">the program entry point is in this file</param>
  2330. /// <returns>a descriptor for the file which contains this module</returns>
  2331. public FileRef MakeFile(byte[] hashBytes, bool hasMetaData, bool entryPoint)
  2332. {
  2333. FileRef file = new FileRef(nameIx,hashBytes,hasMetaData,entryPoint,metaData);
  2334. metaData.AddToTable(MDTable.File,file);
  2335. return file;
  2336. }
  2337. /// <summary>
  2338. /// Add a value class to this module. This is a class declared in
  2339. /// another module of THIS assembly.
  2340. /// </summary>
  2341. /// <param name="nsName">name space name</param>
  2342. /// <param name="name">class name</param>
  2343. /// <returns></returns>
  2344. public ClassRef AddValueClass(string nsName, string name)
  2345. {
  2346. ClassRef aClass = new ClassRef(nsName,name,metaData);
  2347. metaData.AddToTable(MDTable.TypeRef,aClass);
  2348. aClass.SetParent(this);
  2349. aClass.MakeValueClass(ValueClass.ValueType);
  2350. return aClass;
  2351. }
  2352. /// <summary>
  2353. /// Add a class which is declared public in this external module of
  2354. /// THIS assembly. This class will be exported from this assembly.
  2355. /// The ilasm syntax for this is .extern class
  2356. /// </summary>
  2357. /// <param name="attrSet">attributes of the class to be exported</param>
  2358. /// <param name="nsName">name space name</param>
  2359. /// <param name="name">external class name</param>
  2360. /// <param name="declFile">the file where the class is declared</param>
  2361. /// <param name="isValueClass">is this class a value type?</param>
  2362. /// <returns>a descriptor for this external class</returns>
  2363. public ExternClassRef AddExternClass(TypeAttr attrSet, string nsName,
  2364. string name, FileRef declFile,
  2365. bool isValueClass) {
  2366. ExternClassRef cRef = new ExternClassRef(attrSet,nsName,name,declFile,metaData);
  2367. metaData.AddToTable(MDTable.TypeRef,cRef);
  2368. cRef.SetParent(this);
  2369. if (isValueClass) cRef.MakeValueClass(ValueClass.ValueType);
  2370. return cRef;
  2371. }
  2372. /// <summary>
  2373. /// Add a "global" method in another module
  2374. /// </summary>
  2375. /// <param name="name">method name</param>
  2376. /// <param name="retType">return type</param>
  2377. /// <param name="pars">method parameter types</param>
  2378. /// <returns>a descriptor for this method in anther module</returns>
  2379. public MethodRef AddMethod(string name, Type retType, Type[] pars)
  2380. {
  2381. MethodRef meth = new MethodRef(this,name,retType,pars,false,null, 0);
  2382. metaData.AddToTable(MDTable.MemberRef,meth);
  2383. return meth;
  2384. }
  2385. /// <summary>
  2386. /// Add a vararg method to this class
  2387. /// </summary>
  2388. /// <param name="name">method name</param>
  2389. /// <param name="retType">return type</param>
  2390. /// <param name="pars">parameter types</param>
  2391. /// <param name="optPars">optional param types for this vararg method</param>
  2392. /// <returns>a descriptor for this method</returns>
  2393. public MethodRef AddVarArgMethod(string name, Type retType,
  2394. Type[] pars, Type[] optPars) {
  2395. MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
  2396. metaData.AddToTable(MDTable.MemberRef,meth);
  2397. return meth;
  2398. }
  2399. /// <summary>
  2400. /// Add a field in another module
  2401. /// </summary>
  2402. /// <param name="name">field name</param>
  2403. /// <param name="fType">field type</param>
  2404. /// <returns>a descriptor for this field in another module</returns>
  2405. public FieldRef AddField(string name, Type fType)
  2406. {
  2407. FieldRef field = new FieldRef(this,name,fType);
  2408. metaData.AddToTable(MDTable.MemberRef,field);
  2409. return field;
  2410. }
  2411. internal sealed override uint Size(MetaData md)
  2412. {
  2413. return md.StringsIndexSize();
  2414. }
  2415. internal sealed override void Write(FileImage output)
  2416. {
  2417. output.StringsIndex(nameIx);
  2418. }
  2419. internal sealed override uint GetCodedIx(CIx code)
  2420. {
  2421. switch (code) {
  2422. case (CIx.HasCustomAttr) : return 12;
  2423. case (CIx.MemberRefParent) : return 2;
  2424. case (CIx.ResolutionScope) : return 1;
  2425. }
  2426. return 0;
  2427. }
  2428. }
  2429. #region Classes for Constants
  2430. /// <summary>
  2431. /// Descriptor for a constant value
  2432. /// </summary>
  2433. public abstract class Constant {
  2434. protected uint size = 0;
  2435. protected Type type;
  2436. protected uint blobIndex;
  2437. protected bool addedToBlobHeap = false;
  2438. internal Constant() { }
  2439. internal virtual uint GetBlobIndex(MetaData md) { return 0; }
  2440. internal uint GetSize() { return size; }
  2441. internal byte GetTypeIndex() { return type.GetTypeIndex(); }
  2442. internal virtual void Write(BinaryWriter bw) { }
  2443. }
  2444. /// <summary>
  2445. /// Descriptor for a constant value
  2446. /// </summary>
  2447. public abstract class DataConstant : Constant {
  2448. private uint dataOffset = 0;
  2449. internal DataConstant() { }
  2450. public uint DataOffset {
  2451. get { return dataOffset; }
  2452. set { dataOffset = value; }
  2453. }
  2454. }
  2455. /// <summary>
  2456. /// Boolean constant
  2457. /// </summary>
  2458. public class BoolConst : Constant {
  2459. bool val;
  2460. /// <summary>
  2461. /// Create a new boolean constant with the value "val"
  2462. /// </summary>
  2463. /// <param name="val">value of this boolean constant</param>
  2464. public BoolConst(bool val)
  2465. {
  2466. this.val = val;
  2467. size = 1;
  2468. type = PrimitiveType.Boolean;
  2469. }
  2470. internal sealed override uint GetBlobIndex(MetaData md)
  2471. {
  2472. if (!addedToBlobHeap) {
  2473. if (val) blobIndex = md.AddToBlobHeap((sbyte)1);
  2474. else blobIndex = md.AddToBlobHeap((sbyte)0);
  2475. addedToBlobHeap = true;
  2476. }
  2477. return blobIndex;
  2478. }
  2479. internal sealed override void Write(BinaryWriter bw)
  2480. {
  2481. if (val) bw.Write((sbyte)1);
  2482. else bw.Write((sbyte)0);
  2483. }
  2484. }
  2485. public class ByteArrConst : DataConstant {
  2486. byte[] val;
  2487. public ByteArrConst(byte[] val)
  2488. {
  2489. type = PrimitiveType.String;
  2490. this.val = val;
  2491. size = (uint)val.Length;
  2492. }
  2493. public Type Type {
  2494. get { return type; }
  2495. set { type = value; }
  2496. }
  2497. internal sealed override uint GetBlobIndex(MetaData md)
  2498. {
  2499. if (!addedToBlobHeap) {
  2500. blobIndex = md.AddToBlobHeap(val);
  2501. addedToBlobHeap = true;
  2502. }
  2503. return blobIndex;
  2504. }
  2505. internal sealed override void Write(BinaryWriter bw)
  2506. {
  2507. bw.Write(val);
  2508. }
  2509. }
  2510. public class CharConst : Constant {
  2511. char val;
  2512. public CharConst(char val)
  2513. {
  2514. this.val = val;
  2515. size = 2;
  2516. type = PrimitiveType.Char;
  2517. }
  2518. internal sealed override uint GetBlobIndex(MetaData md)
  2519. {
  2520. if (!addedToBlobHeap) {
  2521. blobIndex = md.AddToBlobHeap(val);
  2522. addedToBlobHeap = true;
  2523. }
  2524. return blobIndex;
  2525. }
  2526. internal sealed override void Write(BinaryWriter bw)
  2527. {
  2528. bw.Write(val);
  2529. }
  2530. }
  2531. public class FloatConst : DataConstant {
  2532. float val;
  2533. public FloatConst(float val)
  2534. {
  2535. this.val = val;
  2536. size = 4;
  2537. type = PrimitiveType.Float32;
  2538. }
  2539. internal sealed override uint GetBlobIndex(MetaData md)
  2540. {
  2541. if (!addedToBlobHeap) {
  2542. blobIndex = md.AddToBlobHeap(val);
  2543. addedToBlobHeap = true;
  2544. }
  2545. return blobIndex;
  2546. }
  2547. internal sealed override void Write(BinaryWriter bw)
  2548. {
  2549. bw.Write(val);
  2550. }
  2551. }
  2552. public class DoubleConst : DataConstant {
  2553. double val;
  2554. public DoubleConst(double val)
  2555. {
  2556. this.val = val;
  2557. size = 8;
  2558. type = PrimitiveType.Float64;
  2559. }
  2560. internal sealed override uint GetBlobIndex(MetaData md)
  2561. {
  2562. if (!addedToBlobHeap) {
  2563. blobIndex = md.AddToBlobHeap(val);
  2564. addedToBlobHeap = true;
  2565. }
  2566. return blobIndex;
  2567. }
  2568. internal sealed override void Write(BinaryWriter bw)
  2569. {
  2570. bw.Write(val);
  2571. }
  2572. }
  2573. public class IntConst : DataConstant {
  2574. long val;
  2575. public IntConst(sbyte val)
  2576. {
  2577. this.val = val;
  2578. size = 1;
  2579. type = PrimitiveType.Int8;
  2580. }
  2581. public IntConst(short val)
  2582. {
  2583. this.val = val;
  2584. size = 2;
  2585. type = PrimitiveType.Int16;
  2586. }
  2587. public IntConst(int val)
  2588. {
  2589. this.val = val;
  2590. size = 4;
  2591. type = PrimitiveType.Int32;
  2592. }
  2593. public IntConst(long val)
  2594. {
  2595. this.val = val;
  2596. size = 8;
  2597. type = PrimitiveType.Int64;
  2598. }
  2599. internal sealed override uint GetBlobIndex(MetaData md)
  2600. {
  2601. if (!addedToBlobHeap) {
  2602. switch (size) {
  2603. case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
  2604. case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
  2605. case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
  2606. default : blobIndex = md.AddToBlobHeap(val); break;
  2607. }
  2608. addedToBlobHeap = true;
  2609. }
  2610. return blobIndex;
  2611. }
  2612. internal sealed override void Write(BinaryWriter bw)
  2613. {
  2614. switch (size) {
  2615. case (1) : bw.Write((sbyte)val); break;
  2616. case (2) : bw.Write((short)val); break;
  2617. case (4) : bw.Write((int)val); break;
  2618. default : bw.Write(val); break;
  2619. }
  2620. }
  2621. }
  2622. public class UIntConst : Constant {
  2623. ulong val;
  2624. public UIntConst(byte val)
  2625. {
  2626. this.val = val;
  2627. size = 1;
  2628. type = PrimitiveType.UInt8;
  2629. }
  2630. public UIntConst(ushort val)
  2631. {
  2632. this.val = val;
  2633. size = 2;
  2634. type = PrimitiveType.UInt16;
  2635. }
  2636. public UIntConst(uint val)
  2637. {
  2638. this.val = val;
  2639. size = 4;
  2640. type = PrimitiveType.UInt32;
  2641. }
  2642. public UIntConst(ulong val)
  2643. {
  2644. this.val = val;
  2645. size = 8;
  2646. type = PrimitiveType.UInt64;
  2647. }
  2648. internal sealed override uint GetBlobIndex(MetaData md)
  2649. {
  2650. if (!addedToBlobHeap) {
  2651. switch (size) {
  2652. case (1) : blobIndex = md.AddToBlobHeap((byte)val); break;
  2653. case (2) : blobIndex = md.AddToBlobHeap((ushort)val); break;
  2654. case (4) : blobIndex = md.AddToBlobHeap((uint)val); break;
  2655. default : blobIndex = md.AddToBlobHeap(val); break;
  2656. }
  2657. addedToBlobHeap = true;
  2658. }
  2659. return blobIndex;
  2660. }
  2661. internal sealed override void Write(BinaryWriter bw)
  2662. {
  2663. switch (size) {
  2664. case (1) : bw.Write((byte)val); break;
  2665. case (2) : bw.Write((ushort)val); break;
  2666. case (4) : bw.Write((uint)val); break;
  2667. default : bw.Write(val); break;
  2668. }
  2669. }
  2670. }
  2671. public class StringConst : DataConstant {
  2672. string val;
  2673. public StringConst(string val)
  2674. {
  2675. this.val = val;
  2676. size = (uint)val.Length; // need to add null ??
  2677. type = PrimitiveType.String;
  2678. }
  2679. internal sealed override uint GetBlobIndex(MetaData md)
  2680. {
  2681. if (!addedToBlobHeap) {
  2682. byte [] b = Encoding.Unicode.GetBytes (val);
  2683. blobIndex = md.AddToBlobHeap(b);
  2684. addedToBlobHeap = true;
  2685. }
  2686. return blobIndex;
  2687. }
  2688. internal sealed override void Write(BinaryWriter bw)
  2689. {
  2690. bw.Write(val);
  2691. }
  2692. }
  2693. public class NullConst : Constant {
  2694. public NullConst()
  2695. {
  2696. size = 4;
  2697. type = PrimitiveType.Class;
  2698. }
  2699. internal sealed override uint GetBlobIndex(MetaData md)
  2700. {
  2701. if (!addedToBlobHeap) {
  2702. blobIndex = md.AddToBlobHeap((int)0);
  2703. addedToBlobHeap = true;
  2704. }
  2705. return blobIndex;
  2706. }
  2707. internal sealed override void Write(BinaryWriter bw)
  2708. {
  2709. bw.Write((int)0);
  2710. }
  2711. }
  2712. public class AddressConstant : DataConstant {
  2713. DataConstant data;
  2714. public AddressConstant(DataConstant dConst)
  2715. {
  2716. data = dConst;
  2717. size = 4;
  2718. type = PrimitiveType.TypedRef;
  2719. }
  2720. internal sealed override void Write(BinaryWriter bw)
  2721. {
  2722. ((FileImage)bw).WriteDataRVA(data.DataOffset);
  2723. }
  2724. }
  2725. public class RepeatedConstant : DataConstant {
  2726. DataConstant data;
  2727. uint repCount;
  2728. public RepeatedConstant(DataConstant dConst, int repeatCount)
  2729. {
  2730. data = dConst;
  2731. repCount = (uint)repeatCount;
  2732. int[] sizes = new int[1];
  2733. sizes[0] = repeatCount;
  2734. type = new BoundArray(type,1,sizes);
  2735. size = data.GetSize() * repCount;
  2736. }
  2737. internal sealed override void Write(BinaryWriter bw)
  2738. {
  2739. for (int i=0; i < repCount; i++) {
  2740. data.Write(bw);
  2741. }
  2742. }
  2743. }
  2744. public class ArrayConstant : DataConstant {
  2745. DataConstant[] dataVals;
  2746. public ArrayConstant(DataConstant[] dVals)
  2747. {
  2748. dataVals = dVals;
  2749. for (int i=0; i < dataVals.Length; i++) {
  2750. size += dataVals[i].GetSize();
  2751. }
  2752. }
  2753. internal sealed override void Write(BinaryWriter bw)
  2754. {
  2755. for (int i=0; i < dataVals.Length; i++) {
  2756. dataVals[i].Write(bw);
  2757. }
  2758. }
  2759. }
  2760. public class ClassType : Constant {
  2761. string name;
  2762. Class desc;
  2763. public ClassType(string className)
  2764. {
  2765. name = className;
  2766. type = PrimitiveType.ClassType;
  2767. }
  2768. public ClassType(Class classDesc)
  2769. {
  2770. desc = classDesc;
  2771. type = PrimitiveType.ClassType;
  2772. }
  2773. internal override void Write(BinaryWriter bw)
  2774. {
  2775. if (name == null) name = desc.TypeName();
  2776. bw.Write(name);
  2777. }
  2778. }
  2779. #endregion
  2780. /**************************************************************************/
  2781. /// <summary>
  2782. /// Descriptor for a custom modifier of a type (modopt or modreq)
  2783. /// </summary>
  2784. public class CustomModifiedType : Type {
  2785. Type type;
  2786. Class cmodType;
  2787. /// <summary>
  2788. /// Create a new custom modifier for a type
  2789. /// </summary>
  2790. /// <param name="type">the type to be modified</param>
  2791. /// <param name="cmod">the modifier</param>
  2792. /// <param name="cmodType">the type reference to be associated with the type</param>
  2793. public CustomModifiedType(Type type, CustomModifier cmod, Class cmodType)
  2794. : base((byte)cmod)
  2795. {
  2796. this.type = type;
  2797. this.cmodType = cmodType;
  2798. }
  2799. internal sealed override void TypeSig(MemoryStream str)
  2800. {
  2801. str.WriteByte(typeIndex);
  2802. MetaData.CompressNum(cmodType.TypeDefOrRefToken(),str);
  2803. type.TypeSig(str);
  2804. }
  2805. }
  2806. /**************************************************************************/
  2807. /// <summary>
  2808. /// Base class for Event and Property descriptors
  2809. /// </summary>
  2810. public class Feature : MetaDataElement {
  2811. internal enum MethodType : ushort { Setter = 0x01, Getter, Other = 0x04, AddOn = 0x08,
  2812. RemoveOn = 0x10, Fire = 0x20 }
  2813. private static readonly int INITSIZE = 5;
  2814. private static readonly ushort specialName = 0x200;
  2815. private static readonly ushort rtSpecialName = 0x400;
  2816. protected ClassDef parent;
  2817. protected ushort flags = 0;
  2818. protected string name;
  2819. protected int tide = 0;
  2820. protected uint nameIx;
  2821. protected MethodSemantics[] methods = new MethodSemantics[INITSIZE];
  2822. internal Feature(string name, ClassDef par)
  2823. {
  2824. parent = par;
  2825. this.name = name;
  2826. }
  2827. internal void AddMethod(MethodDef meth, MethodType mType)
  2828. {
  2829. if (tide >= methods.Length) {
  2830. int len = methods.Length;
  2831. MethodSemantics[] mTmp = methods;
  2832. methods = new MethodSemantics[len * 2];
  2833. for (int i=0; i < len; i++) {
  2834. methods[i] = mTmp[i];
  2835. }
  2836. }
  2837. methods[tide++] = new MethodSemantics(mType,meth,this);
  2838. }
  2839. /// <summary>
  2840. /// Set the specialName attribute for this Event or Property
  2841. /// </summary>
  2842. public void SetSpecialName()
  2843. {
  2844. flags |= specialName;
  2845. }
  2846. /// <summary>
  2847. /// Set the RTSpecialName attribute for this Event or Property
  2848. /// </summary>
  2849. public void SetRTSpecialName()
  2850. {
  2851. flags |= rtSpecialName;
  2852. }
  2853. }
  2854. /**************************************************************************/
  2855. /// <summary>
  2856. /// Descriptor for an event
  2857. /// </summary>
  2858. public class Event : Feature {
  2859. Type eventType;
  2860. internal Event(string name, Type eType, ClassDef parent)
  2861. : base(name, parent)
  2862. {
  2863. eventType = eType;
  2864. tabIx = MDTable.Event;
  2865. }
  2866. /// <summary>
  2867. /// Add the addon method to this event
  2868. /// </summary>
  2869. /// <param name="addon">the addon method</param>
  2870. public void AddAddon(MethodDef addon)
  2871. {
  2872. AddMethod(addon,MethodType.AddOn);
  2873. }
  2874. /// <summary>
  2875. /// Add the removeon method to this event
  2876. /// </summary>
  2877. /// <param name="removeOn">the removeon method</param>
  2878. public void AddRemoveOn(MethodDef removeOn)
  2879. {
  2880. AddMethod(removeOn,MethodType.RemoveOn);
  2881. }
  2882. /// <summary>
  2883. /// Add the fire method to this event
  2884. /// </summary>
  2885. /// <param name="fire">the fire method</param>
  2886. public void AddFire(MethodDef fire)
  2887. {
  2888. AddMethod(fire,MethodType.Fire);
  2889. }
  2890. /// <summary>
  2891. /// Add another method to this event
  2892. /// </summary>
  2893. /// <param name="other">the method to be added</param>
  2894. public void AddOther(MethodDef other)
  2895. {
  2896. AddMethod(other,MethodType.Other);
  2897. }
  2898. internal sealed override void BuildTables(MetaData md)
  2899. {
  2900. if (done) return;
  2901. nameIx = md.AddToStringsHeap(name);
  2902. for (int i=0; i < tide; i++) {
  2903. md.AddToTable(MDTable.MethodSemantics,methods[i]);
  2904. }
  2905. done = true;
  2906. }
  2907. internal sealed override uint Size(MetaData md)
  2908. {
  2909. return 2 + md.StringsIndexSize() + md.CodedIndexSize(CIx.TypeDefOrRef);
  2910. }
  2911. internal sealed override void Write(FileImage output)
  2912. {
  2913. output.Write(flags);
  2914. output.StringsIndex(nameIx);
  2915. output.WriteCodedIndex(CIx.TypeDefOrRef,eventType);
  2916. }
  2917. internal sealed override uint GetCodedIx(CIx code)
  2918. {
  2919. switch (code) {
  2920. case (CIx.HasCustomAttr) : return 10;
  2921. case (CIx.HasSemantics) : return 0;
  2922. }
  2923. return 0;
  2924. }
  2925. }
  2926. /**************************************************************************/
  2927. /// <summary>
  2928. /// Descriptor for the Property of a class
  2929. /// </summary>
  2930. public class Property : Feature {
  2931. private static readonly byte PropertyTag = 0x8;
  2932. private bool instance;
  2933. MethodDef getterMeth;
  2934. ConstantElem constVal;
  2935. uint typeBlobIx = 0;
  2936. Type[] parList;
  2937. Type returnType;
  2938. uint numPars = 0;
  2939. internal Property(string name, Type retType, Type[] pars, ClassDef parent) : base(name, parent)
  2940. {
  2941. returnType = retType;
  2942. parList = pars;
  2943. if (pars != null) numPars = (uint)pars.Length;
  2944. tabIx = MDTable.Property;
  2945. }
  2946. /// <summary>
  2947. /// Add a set method to this property
  2948. /// </summary>
  2949. /// <param name="setter">the set method</param>
  2950. public void AddSetter(MethodDef setter)
  2951. {
  2952. AddMethod(setter,MethodType.Setter);
  2953. }
  2954. /// <summary>
  2955. /// Add a get method to this property
  2956. /// </summary>
  2957. /// <param name="getter">the get method</param>
  2958. public void AddGetter(MethodDef getter)
  2959. {
  2960. AddMethod(getter,MethodType.Getter);
  2961. getterMeth = getter;
  2962. }
  2963. /// <summary>
  2964. /// Add another method to this property
  2965. /// </summary>
  2966. /// <param name="other">the method</param>
  2967. public void AddOther(MethodDef other)
  2968. {
  2969. AddMethod(other,MethodType.Other);
  2970. }
  2971. /// <summary>
  2972. /// Add an initial value for this property
  2973. /// </summary>
  2974. /// <param name="constVal">the initial value for this property</param>
  2975. public void AddInitValue(Constant constVal)
  2976. {
  2977. this.constVal = new ConstantElem(this,constVal);
  2978. }
  2979. public void SetInstance (bool isInstance)
  2980. {
  2981. this.instance = isInstance;
  2982. }
  2983. internal sealed override void BuildTables(MetaData md)
  2984. {
  2985. if (done) return;
  2986. nameIx = md.AddToStringsHeap(name);
  2987. MemoryStream sig = new MemoryStream();
  2988. byte tag = PropertyTag;
  2989. if (instance)
  2990. tag |= 0x20;
  2991. sig.WriteByte(tag);
  2992. MetaData.CompressNum(numPars,sig);
  2993. returnType.TypeSig(sig);
  2994. for (int i=0; i < numPars; i++) {
  2995. parList[i].TypeSig(sig);
  2996. }
  2997. typeBlobIx = md.AddToBlobHeap(sig.ToArray());
  2998. for (int i=0; i < tide; i++) {
  2999. md.AddToTable(MDTable.MethodSemantics,methods[i]);
  3000. }
  3001. if (constVal != null) {
  3002. md.AddToTable(MDTable.Constant,constVal);
  3003. constVal.BuildTables(md);
  3004. }
  3005. done = true;
  3006. }
  3007. internal sealed override uint Size(MetaData md)
  3008. {
  3009. return 2 + md.StringsIndexSize() + md.BlobIndexSize();
  3010. }
  3011. internal sealed override void Write(FileImage output)
  3012. {
  3013. output.Write(flags);
  3014. output.StringsIndex(nameIx);
  3015. output.BlobIndex(typeBlobIx);
  3016. }
  3017. internal sealed override uint GetCodedIx(CIx code)
  3018. {
  3019. switch (code) {
  3020. case (CIx.HasCustomAttr) : return 9;
  3021. case (CIx.HasConst) : return 2;
  3022. case (CIx.HasSemantics) : return 1;
  3023. }
  3024. return 0;
  3025. }
  3026. }
  3027. /**************************************************************************/
  3028. /// <summary>
  3029. /// Base class for field/methods (member of a class)
  3030. /// </summary>
  3031. public abstract class Member : MetaDataElement {
  3032. protected string name;
  3033. protected uint nameIx = 0, sigIx = 0;
  3034. internal Member(string memName)
  3035. {
  3036. name = memName;
  3037. tabIx = MDTable.MemberRef;
  3038. }
  3039. }
  3040. /*****************************************************************************/
  3041. /// <summary>
  3042. /// Descriptor for a field of a class
  3043. /// </summary>
  3044. public abstract class Field : Member {
  3045. protected static readonly byte FieldSig = 0x6;
  3046. protected Type type;
  3047. internal Field(string pfName, Type pfType) : base(pfName)
  3048. {
  3049. type = pfType;
  3050. }
  3051. }
  3052. /**************************************************************************/
  3053. /// <summary>
  3054. /// Descriptor for a field defined in a class of THIS assembly/module
  3055. /// </summary>
  3056. public class FieldDef : Field {
  3057. //private static readonly uint PInvokeImpl = 0x2000;
  3058. private static readonly ushort HasFieldRVA = 0x100;
  3059. private static readonly ushort HasDefault = 0x8000;
  3060. FieldRVA rva;
  3061. ConstantElem constVal;
  3062. FieldLayout layout;
  3063. FieldMarshal marshalInfo;
  3064. ushort flags;
  3065. internal FieldDef(string name, Type fType) : base(name,fType)
  3066. {
  3067. tabIx = MDTable.Field;
  3068. }
  3069. internal FieldDef(FieldAttr attrSet, string name, Type fType) : base(name, fType)
  3070. {
  3071. flags = (ushort)attrSet;
  3072. tabIx = MDTable.Field;
  3073. }
  3074. /// <summary>
  3075. /// Add an attribute(s) to this field
  3076. /// </summary>
  3077. /// <param name="fa">the attribute(s) to be added</param>
  3078. public void AddFieldAttr(FieldAttr fa)
  3079. {
  3080. flags |= (ushort)fa;
  3081. }
  3082. /// <summary>
  3083. /// Add a value for this field
  3084. /// </summary>
  3085. /// <param name="val">the value for the field</param>
  3086. public void AddValue(Constant val)
  3087. {
  3088. constVal = new ConstantElem(this,val);
  3089. flags |= HasDefault;
  3090. }
  3091. /// <summary>
  3092. /// Add an initial value for this field (at dataLabel) (.data)
  3093. /// </summary>
  3094. /// <param name="val">the value for the field</param>
  3095. /// <param name="repeatVal">the number of repetitions of this value</param>
  3096. public void AddDataValue(DataConstant val)
  3097. {
  3098. flags |= HasFieldRVA;
  3099. rva = new FieldRVA(this,val);
  3100. }
  3101. /// <summary>
  3102. /// Set the offset of the field. Used for sequential or explicit classes.
  3103. /// (.field [offs])
  3104. /// </summary>
  3105. /// <param name="offs">field offset</param>
  3106. public void SetOffset(uint offs)
  3107. {
  3108. layout = new FieldLayout(this,offs);
  3109. }
  3110. /// <summary>
  3111. /// Set the marshalling info for a field
  3112. /// </summary>
  3113. /// <param name="mInf"></param>
  3114. public void SetMarshalInfo(NativeType marshallType)
  3115. {
  3116. flags |= (ushort) FieldAttr.HasFieldMarshal;
  3117. marshalInfo = new FieldMarshal(this,marshallType);
  3118. }
  3119. internal sealed override void BuildTables(MetaData md)
  3120. {
  3121. if (done) return;
  3122. nameIx = md.AddToStringsHeap(name);
  3123. MemoryStream sig = new MemoryStream();
  3124. sig.WriteByte(FieldSig);
  3125. type.TypeSig(sig);
  3126. sigIx = md.AddToBlobHeap(sig.ToArray());
  3127. if (rva != null) {
  3128. md.AddToTable(MDTable.FieldRVA,rva);
  3129. rva.BuildTables(md);
  3130. } else if (constVal != null) {
  3131. md.AddToTable(MDTable.Constant,constVal);
  3132. constVal.BuildTables(md);
  3133. }
  3134. if (layout != null) md.AddToTable(MDTable.FieldLayout,layout);
  3135. if (marshalInfo != null) {
  3136. md.AddToTable(MDTable.FieldMarshal,marshalInfo);
  3137. marshalInfo.BuildTables(md);
  3138. }
  3139. done = true;
  3140. }
  3141. internal sealed override uint Size(MetaData md)
  3142. {
  3143. return 2 + md.StringsIndexSize() + md.BlobIndexSize();
  3144. }
  3145. internal sealed override void Write(FileImage output)
  3146. {
  3147. output.Write(flags);
  3148. output.StringsIndex(nameIx);
  3149. output.BlobIndex(sigIx);
  3150. }
  3151. internal sealed override uint GetCodedIx(CIx code)
  3152. {
  3153. switch (code) {
  3154. case (CIx.HasConst) : return 0;
  3155. case (CIx.HasCustomAttr) : return 1;
  3156. case (CIx.HasFieldMarshal) : return 0;
  3157. case (CIx.MemberForwarded) : return 0;
  3158. }
  3159. return 0;
  3160. }
  3161. }
  3162. /**************************************************************************/
  3163. /// <summary>
  3164. /// Descriptor for a field of a class defined in another assembly/module
  3165. /// </summary>
  3166. public class FieldRef : Field {
  3167. MetaDataElement parent;
  3168. internal FieldRef(MetaDataElement paren, string name, Type fType) : base(name, fType)
  3169. {
  3170. parent = paren;
  3171. }
  3172. internal sealed override void BuildTables(MetaData md)
  3173. {
  3174. if (done) return;
  3175. nameIx = md.AddToStringsHeap(name);
  3176. MemoryStream sig = new MemoryStream();
  3177. sig.WriteByte(FieldSig);
  3178. type.TypeSig(sig);
  3179. sigIx = md.AddToBlobHeap(sig.ToArray());
  3180. done = true;
  3181. }
  3182. internal sealed override uint Size(MetaData md)
  3183. {
  3184. return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
  3185. }
  3186. internal sealed override void Write(FileImage output)
  3187. {
  3188. output.WriteCodedIndex(CIx.MemberRefParent,parent);
  3189. output.StringsIndex(nameIx);
  3190. output.BlobIndex(sigIx);
  3191. }
  3192. internal sealed override uint GetCodedIx(CIx code) { return 6; }
  3193. }
  3194. /**************************************************************************/
  3195. /// <summary>
  3196. /// Base class for Method Descriptors
  3197. /// </summary>
  3198. public abstract class Method : Member {
  3199. internal Method (string methName) : base (methName)
  3200. {}
  3201. public abstract void AddCallConv(CallConv cconv);
  3202. internal abstract void TypeSig(MemoryStream sig);
  3203. internal abstract uint GetSigIx(MetaData md);
  3204. }
  3205. /**************************************************************************/
  3206. /// <summary>
  3207. /// Descriptor for a method defined in THIS assembly/module
  3208. /// IL .method
  3209. /// </summary>
  3210. public class MethodDef : Method {
  3211. private static readonly ushort PInvokeImpl = 0x2000;
  3212. //private static readonly uint UnmanagedExport = 0x0008;
  3213. // private static readonly byte LocalSigByte = 0x7;
  3214. uint parIx = 0, textOffset = 0;
  3215. private CallConv callConv = CallConv.Default;
  3216. private int gen_param_count;
  3217. MetaData metaData;
  3218. CILInstructions code;
  3219. ArrayList securityActions = new ArrayList();
  3220. Param[] parList;
  3221. Local[] locals;
  3222. bool initLocals;
  3223. ushort methFlags = 0, implFlags = 0;
  3224. int maxStack = 0, numPars = 0;
  3225. bool entryPoint = false;
  3226. LocalSig localSig;
  3227. ArrayList varArgSigList;
  3228. ImplMap pinvokeImpl;
  3229. Param ret_param;
  3230. internal MethodDef (MetaData md, string name, Param ret_param, Param [] pars)
  3231. : this (md, 0, 0, name, ret_param, pars)
  3232. {
  3233. }
  3234. internal MethodDef (MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name,
  3235. Param ret_param, Param [] pars)
  3236. : base (name)
  3237. {
  3238. methFlags = (ushort)mAttrSet;
  3239. implFlags = (ushort)iAttrSet;
  3240. this.ret_param = ret_param;
  3241. metaData = md;
  3242. parList = pars;
  3243. if (parList != null)
  3244. numPars = parList.Length;
  3245. tabIx = MDTable.Method;
  3246. }
  3247. internal Param[] GetPars()
  3248. {
  3249. return parList;
  3250. }
  3251. internal override uint GetSigIx(MetaData md)
  3252. {
  3253. MemoryStream sig = new MemoryStream();
  3254. TypeSig(sig);
  3255. return md.AddToBlobHeap(sig.ToArray());
  3256. }
  3257. public override void AddCallConv(CallConv cconv)
  3258. {
  3259. callConv |= cconv;
  3260. }
  3261. /// <summary>
  3262. /// Add some attributes to this method descriptor
  3263. /// </summary>
  3264. /// <param name="ma">the attributes to be added</param>
  3265. public void AddMethAttribute(MethAttr ma)
  3266. {
  3267. methFlags |= (ushort)ma;
  3268. }
  3269. /// <summary>
  3270. /// Add some implementation attributes to this method descriptor
  3271. /// </summary>
  3272. /// <param name="ia">the attributes to be added</param>
  3273. public void AddImplAttribute(ImplAttr ia)
  3274. {
  3275. implFlags |= (ushort)ia;
  3276. }
  3277. public void AddPInvokeInfo(ModuleRef scope, string methName,
  3278. PInvokeAttr callAttr) {
  3279. pinvokeImpl = new ImplMap((ushort)callAttr,this,methName,scope);
  3280. methFlags |= PInvokeImpl;
  3281. }
  3282. /// <summary>
  3283. /// Add a named generic type parameter
  3284. /// </summary>
  3285. public GenericParameter AddGenericParameter (short index, string name)
  3286. {
  3287. return AddGenericParameter (index, name, 0);
  3288. }
  3289. /// <summary>
  3290. /// Add a named generic type parameter with attributes
  3291. /// </summary>
  3292. public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
  3293. {
  3294. GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
  3295. metaData.AddToTable (MDTable.GenericParam, gp);
  3296. gen_param_count ++;
  3297. return gp;
  3298. }
  3299. /// <summary>
  3300. /// Set the maximum stack height for this method
  3301. /// </summary>
  3302. /// <param name="maxStack">the maximum height of the stack</param>
  3303. public void SetMaxStack(int maxStack)
  3304. {
  3305. this.maxStack = maxStack;
  3306. }
  3307. /// <summary>
  3308. /// Add local variables to this method
  3309. /// </summary>
  3310. /// <param name="locals">the locals to be added</param>
  3311. /// <param name="initLocals">are locals initialised to default values</param>
  3312. public void AddLocals(Local[] locals, bool initLocals)
  3313. {
  3314. this.locals = locals;
  3315. this.initLocals = initLocals;
  3316. }
  3317. /* Add Marshal info for return type */
  3318. public void AddRetTypeMarshallInfo (NativeType marshallType)
  3319. {
  3320. ret_param.AddMarshallInfo (marshallType);
  3321. }
  3322. /// <summary>
  3323. /// Mark this method as having an entry point
  3324. /// </summary>
  3325. public void DeclareEntryPoint()
  3326. {
  3327. entryPoint = true;
  3328. }
  3329. /// <summary>
  3330. /// Create a code buffer for this method to add the IL instructions to
  3331. /// </summary>
  3332. /// <returns>a buffer for this method's IL instructions</returns>
  3333. public CILInstructions CreateCodeBuffer()
  3334. {
  3335. code = new CILInstructions(metaData);
  3336. return code;
  3337. }
  3338. /// <summary>
  3339. /// Make a method reference descriptor for this method to be used
  3340. /// as a callsite signature for this vararg method
  3341. /// </summary>
  3342. /// <param name="optPars">the optional pars for the vararg method call</param>
  3343. /// <returns></returns>
  3344. public MethodRef MakeVarArgSignature(Type[] optPars)
  3345. {
  3346. Type[] pars = new Type[numPars];
  3347. MethodRef varArgSig;
  3348. for (int i=0; i < numPars; i++) {
  3349. pars[i] = parList[i].GetParType();
  3350. }
  3351. varArgSig = new MethodRef (this, name, ret_param.GetParType (), pars, true, optPars, 0);
  3352. if (varArgSigList == null)
  3353. varArgSigList = new ArrayList ();
  3354. varArgSigList.Add (varArgSig);
  3355. return varArgSig;
  3356. }
  3357. internal sealed override void TypeSig(MemoryStream sig)
  3358. {
  3359. sig.WriteByte((byte)callConv);
  3360. if ((callConv & CallConv.Generic) == CallConv.Generic)
  3361. MetaData.CompressNum ((uint) gen_param_count, sig);
  3362. MetaData.CompressNum((uint)numPars,sig);
  3363. ret_param.seqNo = 0;
  3364. ret_param.TypeSig (sig);
  3365. for (ushort i=0; i < numPars; i++) {
  3366. parList[i].seqNo = (ushort)(i+1);
  3367. parList[i].TypeSig(sig);
  3368. }
  3369. }
  3370. internal sealed override void BuildTables(MetaData md)
  3371. {
  3372. if (done) return;
  3373. if (pinvokeImpl != null) {
  3374. md.AddToTable(MDTable.ImplMap,pinvokeImpl);
  3375. pinvokeImpl.BuildTables(md);
  3376. }
  3377. if (entryPoint) md.SetEntryPoint(this);
  3378. uint locToken = 0;
  3379. if (locals != null) {
  3380. localSig = new LocalSig(locals);
  3381. md.AddToTable(MDTable.StandAloneSig,localSig);
  3382. localSig.BuildTables(md);
  3383. locToken = localSig.Token();
  3384. }
  3385. if (code != null) {
  3386. code.CheckCode(locToken,initLocals,maxStack);
  3387. textOffset = md.AddCode(code);
  3388. }
  3389. nameIx = md.AddToStringsHeap(name);
  3390. sigIx = GetSigIx(md);
  3391. parIx = md.TableIndex(MDTable.Param);
  3392. if (ret_param.HasMarshalInfo || ret_param.HasCustomAttr) {
  3393. md.AddToTable(MDTable.Param, ret_param);
  3394. ret_param.BuildTables(md);
  3395. }
  3396. for (int i=0; i < numPars; i++) {
  3397. md.AddToTable(MDTable.Param,parList[i]);
  3398. parList[i].BuildTables(md);
  3399. }
  3400. if (varArgSigList != null) {
  3401. foreach (MethodRef varArgSig in varArgSigList) {
  3402. md.AddToTable(MDTable.MemberRef,varArgSig);
  3403. varArgSig.BuildTables(md);
  3404. }
  3405. }
  3406. // Console.WriteLine("method has " + numPars + " parameters");
  3407. done = true;
  3408. }
  3409. internal sealed override uint Size(MetaData md)
  3410. {
  3411. return 8 + md.StringsIndexSize() + md.BlobIndexSize() + md.TableIndexSize(MDTable.Param);
  3412. }
  3413. internal sealed override void Write(FileImage output)
  3414. {
  3415. if (ZeroRva ()) output.Write(0);
  3416. else output.WriteCodeRVA(textOffset);
  3417. output.Write(implFlags);
  3418. output.Write(methFlags);
  3419. output.StringsIndex(nameIx);
  3420. output.BlobIndex(sigIx);
  3421. output.WriteIndex(MDTable.Param,parIx);
  3422. }
  3423. internal bool ZeroRva ()
  3424. {
  3425. return (((methFlags & (ushort)MethAttr.Abstract) != 0) ||
  3426. ((implFlags & (ushort)ImplAttr.Runtime) != 0) ||
  3427. ((implFlags & (ushort)ImplAttr.InternalCall) != 0) ||
  3428. (pinvokeImpl != null)); // TODO: Not entirely true but works for now
  3429. }
  3430. internal sealed override uint GetCodedIx(CIx code)
  3431. {
  3432. switch (code) {
  3433. case (CIx.HasCustomAttr) : return 0;
  3434. case (CIx.HasDeclSecurity) : return 1;
  3435. case (CIx.MemberRefParent) : return 3;
  3436. case (CIx.MethodDefOrRef) : return 0;
  3437. case (CIx.MemberForwarded) : return 1;
  3438. case (CIx.CustomAttributeType) : return 2;
  3439. case (CIx.TypeOrMethodDef) : return 1;
  3440. }
  3441. return 0;
  3442. }
  3443. }
  3444. /**************************************************************************/
  3445. /// <summary>
  3446. /// Descriptor for a method defined in another assembly/module
  3447. /// </summary>
  3448. public class MethodRef : Method {
  3449. private static readonly byte Sentinel = 0x41;
  3450. Type[] parList, optParList;
  3451. MetaDataElement parent;
  3452. uint numPars = 0, numOptPars = 0;
  3453. CallConv callConv = CallConv.Default;
  3454. Type retType;
  3455. int gen_param_count;
  3456. internal MethodRef(MetaDataElement paren, string name, Type retType,
  3457. Type[] pars, bool varArgMeth, Type[] optPars, int gen_param_count) : base(name)
  3458. {
  3459. parent = paren;
  3460. parList = pars;
  3461. this.retType = retType;
  3462. if (parList != null) numPars = (uint)parList.Length;
  3463. if (varArgMeth) {
  3464. optParList = optPars;
  3465. if (optParList != null) numOptPars = (uint)optParList.Length;
  3466. callConv = CallConv.Vararg;
  3467. }
  3468. this.gen_param_count = gen_param_count;
  3469. }
  3470. internal override uint GetSigIx(MetaData md)
  3471. {
  3472. MemoryStream sig = new MemoryStream();
  3473. TypeSig(sig);
  3474. return md.AddToBlobHeap(sig.ToArray());
  3475. }
  3476. public override void AddCallConv(CallConv cconv)
  3477. {
  3478. callConv |= cconv;
  3479. }
  3480. internal sealed override void TypeSig(MemoryStream sig)
  3481. {
  3482. sig.WriteByte((byte)callConv);
  3483. if ((callConv & CallConv.Generic) == CallConv.Generic)
  3484. MetaData.CompressNum ((uint) gen_param_count, sig);
  3485. MetaData.CompressNum(numPars+numOptPars,sig);
  3486. retType.TypeSig(sig);
  3487. for (int i=0; i < numPars; i++) {
  3488. parList[i].TypeSig(sig);
  3489. }
  3490. if (numOptPars > 0) {
  3491. sig.WriteByte(Sentinel);
  3492. for (int i=0; i < numOptPars; i++) {
  3493. optParList[i].TypeSig(sig);
  3494. }
  3495. }
  3496. }
  3497. internal sealed override void BuildTables(MetaData md)
  3498. {
  3499. if (done) return;
  3500. nameIx = md.AddToStringsHeap(name);
  3501. sigIx = GetSigIx(md);
  3502. done = true;
  3503. }
  3504. internal sealed override uint Size(MetaData md)
  3505. {
  3506. return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
  3507. }
  3508. internal sealed override void Write(FileImage output)
  3509. {
  3510. output.WriteCodedIndex(CIx.MemberRefParent,parent);
  3511. output.StringsIndex(nameIx);
  3512. output.BlobIndex(sigIx);
  3513. }
  3514. internal sealed override uint GetCodedIx(CIx code)
  3515. {
  3516. switch (code) {
  3517. case (CIx.HasCustomAttr) : return 6;
  3518. case (CIx.MethodDefOrRef) : return 1;
  3519. case (CIx.CustomAttributeType) : return 3;
  3520. }
  3521. return 0;
  3522. }
  3523. }
  3524. /**************************************************************************/
  3525. /// <summary>
  3526. /// Descriptors for native types used for marshalling
  3527. /// </summary>
  3528. public class NativeType {
  3529. public static readonly NativeType Void = new NativeType(0x01);
  3530. public static readonly NativeType Boolean = new NativeType(0x02);
  3531. public static readonly NativeType Int8 = new NativeType(0x03);
  3532. public static readonly NativeType UInt8 = new NativeType(0x04);
  3533. public static readonly NativeType Int16 = new NativeType(0x05);
  3534. public static readonly NativeType UInt16 = new NativeType(0x06);
  3535. public static readonly NativeType Int32 = new NativeType(0x07);
  3536. public static readonly NativeType UInt32 = new NativeType(0x08);
  3537. public static readonly NativeType Int64 = new NativeType(0x09);
  3538. public static readonly NativeType UInt64 = new NativeType(0x0A);
  3539. public static readonly NativeType Float32 = new NativeType(0x0B);
  3540. public static readonly NativeType Float64 = new NativeType(0x0C);
  3541. public static readonly NativeType Currency = new NativeType(0x0F);
  3542. public static readonly NativeType BStr = new NativeType(0x13);
  3543. public static readonly NativeType LPStr = new NativeType(0x14);
  3544. public static readonly NativeType LPWStr = new NativeType(0x15);
  3545. public static readonly NativeType LPTStr = new NativeType(0x16);
  3546. public static readonly NativeType FixedSysString = new NativeType(0x17);
  3547. public static readonly NativeType IUnknown = new NativeType(0x19);
  3548. public static readonly NativeType IDispatch = new NativeType(0x1A);
  3549. public static readonly NativeType Struct = new NativeType(0x1B);
  3550. public static readonly NativeType Interface = new NativeType(0x1C);
  3551. public static readonly NativeType Int = new NativeType(0x1F);
  3552. public static readonly NativeType UInt = new NativeType(0x20);
  3553. public static readonly NativeType ByValStr = new NativeType(0x22);
  3554. public static readonly NativeType AnsiBStr = new NativeType(0x23);
  3555. public static readonly NativeType TBstr = new NativeType(0x24);
  3556. public static readonly NativeType VariantBool = new NativeType(0x25);
  3557. public static readonly NativeType FuncPtr = new NativeType(0x26);
  3558. public static readonly NativeType AsAny = new NativeType(0x28);
  3559. public static readonly NativeType LPStruct = new NativeType(0x2b);
  3560. public static readonly NativeType Error = new NativeType(0x2d);
  3561. protected byte typeIndex;
  3562. internal NativeType(byte tyIx) { typeIndex = tyIx; }
  3563. internal byte GetTypeIndex() { return typeIndex; }
  3564. internal virtual byte[] ToBlob()
  3565. {
  3566. byte[] bytes = new byte[1];
  3567. bytes[0] = GetTypeIndex();
  3568. return bytes;
  3569. }
  3570. }
  3571. public class FixedSysString : NativeType {
  3572. uint size;
  3573. public FixedSysString (uint size) : base (NativeType.FixedSysString.GetTypeIndex ())
  3574. {
  3575. this.size = size;
  3576. }
  3577. internal override byte [] ToBlob ()
  3578. {
  3579. MemoryStream str = new MemoryStream ();
  3580. str.WriteByte (GetTypeIndex ());
  3581. MetaData.CompressNum (size, str);
  3582. return str.ToArray ();
  3583. }
  3584. }
  3585. public class NativeArray : NativeType {
  3586. NativeType elemType;
  3587. int numElem = -1, parNum = -1, elemMult = -1;
  3588. public NativeArray(NativeType elemType) : this (elemType, -1, -1, -1)
  3589. {
  3590. this.elemType = elemType;
  3591. }
  3592. /* public NativeArray(NativeType elemType, int len) : base(0x2A) {
  3593. this.elemType = elemType;
  3594. this.len = len;
  3595. }
  3596. */
  3597. public NativeArray(NativeType elemType, int numElem, int parNumForLen, int elemMult) : base(0x2A)
  3598. {
  3599. this.elemType = elemType;
  3600. this.numElem = numElem;
  3601. parNum = parNumForLen;
  3602. this.elemMult = elemMult;
  3603. }
  3604. public NativeArray(NativeType elemType, int numElem, int parNumForLen)
  3605. : this (elemType, numElem, parNumForLen, -1)
  3606. {
  3607. }
  3608. internal override byte[] ToBlob()
  3609. {
  3610. MemoryStream str = new MemoryStream();
  3611. str.WriteByte(GetTypeIndex());
  3612. if (elemType == null) str.WriteByte(0x50); // no info (MAX)
  3613. else str.WriteByte(elemType.GetTypeIndex());
  3614. /* see : mono/metadata/metadata.c:mono_metadata_parse_marshal_spec
  3615. * LAMESPEC: Older spec versions say elemMult comes before
  3616. * len. Newer spec versions don't talk about elemMult at
  3617. * all, but csc still emits it, and it is used to distinguish
  3618. * between parNum being 0, and parNum being omitted.
  3619. */
  3620. if (parNum == -1)
  3621. // <native_type> []
  3622. return str.ToArray ();
  3623. MetaData.CompressNum((uint) parNum,str);
  3624. if (numElem != -1) {
  3625. MetaData.CompressNum ((uint) numElem, str);
  3626. if (elemMult != -1)
  3627. // <native_type> [ int32 ]
  3628. MetaData.CompressNum((uint) elemMult,str);
  3629. //else <native_type> [ int32 + int32 ]
  3630. } else if (elemMult != -1) {
  3631. // When can this occur ?
  3632. MetaData.CompressNum (0, str);
  3633. MetaData.CompressNum((uint) elemMult,str);
  3634. }
  3635. //else <native_type> [ + int32 ]
  3636. return str.ToArray();
  3637. }
  3638. }
  3639. public class SafeArray : NativeType {
  3640. SafeArrayType elemType;
  3641. bool hasElemType;
  3642. public SafeArray() : base(0x1D)
  3643. {
  3644. }
  3645. public SafeArray(SafeArrayType elemType) : base(0x1D)
  3646. {
  3647. this.elemType = elemType;
  3648. hasElemType = true;
  3649. }
  3650. internal override byte[] ToBlob()
  3651. {
  3652. byte[] bytes = new byte[hasElemType ? 2 : 1];
  3653. bytes[0] = GetTypeIndex();
  3654. if (hasElemType)
  3655. bytes[1] = (byte)elemType;
  3656. return bytes;
  3657. }
  3658. }
  3659. public class FixedArray : NativeType {
  3660. NativeType elemType;
  3661. uint numElem;
  3662. //public FixedArray(NativeType elemType, int numElems) : base(0x1E) {
  3663. public FixedArray(int numElems) : base(0x1E)
  3664. {
  3665. //this.elemType = elemType;
  3666. numElem = (uint)numElems;
  3667. }
  3668. internal override byte[] ToBlob()
  3669. {
  3670. MemoryStream str = new MemoryStream();
  3671. str.WriteByte(GetTypeIndex());
  3672. MetaData.CompressNum(numElem,str);
  3673. /* FIXME:
  3674. fixed array [5] lpstr [2]
  3675. This format is not supported by ilasm 1.1.4322.2032,
  3676. but is supported by 2.0.5125..
  3677. ilasm 1.1 only supports "fixed array [5]"
  3678. if (elemType == null) str.WriteByte(0x50); // no info (MAX)
  3679. else str.WriteByte(elemType.GetTypeIndex());*/
  3680. return str.ToArray();
  3681. }
  3682. }
  3683. public class CustomMarshaller : NativeType {
  3684. string typeName;
  3685. string marshallerName;
  3686. string cookie;
  3687. public CustomMarshaller(string typeNameOrGUID, string marshallerName,
  3688. string optCookie) : base(0x2C)
  3689. {
  3690. typeName = typeNameOrGUID;
  3691. this.marshallerName = marshallerName;
  3692. cookie = optCookie;
  3693. }
  3694. public CustomMarshaller(string marshallerName, string optCookie)
  3695. :this (null, marshallerName, optCookie)
  3696. {
  3697. }
  3698. internal override byte[] ToBlob()
  3699. {
  3700. MemoryStream str = new MemoryStream();
  3701. BinaryWriter bw = new BinaryWriter(str,new UTF8Encoding());
  3702. bw.Write(GetTypeIndex());
  3703. //Native type name & unmanaged type - unused
  3704. //See mono/metadata/metadata.c : mono_metadata_parse_marshal_spec
  3705. bw.Write ((byte) 0); // Native Type name, unused
  3706. bw.Write ((byte) 0); // Unmanaged type, unused
  3707. if (marshallerName != null) {
  3708. MetaData.CompressNum ((uint)marshallerName.Length, str);
  3709. bw.Write(marshallerName.ToCharArray());
  3710. } else {
  3711. bw.Write ((byte) 0);
  3712. }
  3713. if (cookie != null) {
  3714. MetaData.CompressNum ((uint)cookie.Length, str);
  3715. bw.Write(cookie.ToCharArray());
  3716. } else {
  3717. bw.Write ((byte) 0);
  3718. }
  3719. bw.Flush();
  3720. return str.ToArray();
  3721. }
  3722. }
  3723. /**************************************************************************/
  3724. /// <summary>
  3725. /// Descriptor for the Primitive types defined in IL
  3726. /// </summary>
  3727. public class PrimitiveType : Type {
  3728. private string name;
  3729. private int systemTypeIndex;
  3730. public static int NumSystemTypes = 18;
  3731. public static readonly PrimitiveType Void = new PrimitiveType(0x01,"Void",0);
  3732. public static readonly PrimitiveType Boolean = new PrimitiveType(0x02,"Boolean",1);
  3733. public static readonly PrimitiveType Char = new PrimitiveType(0x03,"Char",2);
  3734. public static readonly PrimitiveType Int8 = new PrimitiveType(0x04,"SByte",3);
  3735. public static readonly PrimitiveType UInt8 = new PrimitiveType(0x05,"Byte",4);
  3736. public static readonly PrimitiveType Int16 = new PrimitiveType(0x06,"Int16",5);
  3737. public static readonly PrimitiveType UInt16 = new PrimitiveType(0x07,"UInt16",6);
  3738. public static readonly PrimitiveType Int32 = new PrimitiveType(0x08,"Int32",7);
  3739. public static readonly PrimitiveType UInt32 = new PrimitiveType(0x09,"UInt32",8);
  3740. public static readonly PrimitiveType Int64 = new PrimitiveType(0x0A,"Int64",9);
  3741. public static readonly PrimitiveType UInt64 = new PrimitiveType(0x0B,"UInt64",10);
  3742. public static readonly PrimitiveType Float32 = new PrimitiveType(0x0C,"Single",11);
  3743. public static readonly PrimitiveType Float64 = new PrimitiveType(0x0D,"Double",12);
  3744. public static readonly PrimitiveType String = new PrimitiveType(0x0E,"String",13);
  3745. internal static readonly PrimitiveType Class = new PrimitiveType(0x12);
  3746. internal static readonly PrimitiveType Var = new PrimitiveType(0x13);
  3747. internal static readonly PrimitiveType GenericInst = new PrimitiveType(0x15);
  3748. public static readonly PrimitiveType TypedRef = new PrimitiveType(0x16,"TypedReference",14);
  3749. public static readonly PrimitiveType IntPtr = new PrimitiveType(0x18,"IntPtr",15);
  3750. public static readonly PrimitiveType UIntPtr = new PrimitiveType(0x19,"UIntPtr",16);
  3751. public static readonly PrimitiveType Object = new PrimitiveType(0x1C,"Object",17);
  3752. internal static readonly PrimitiveType ClassType = new PrimitiveType(0x50);
  3753. internal static readonly PrimitiveType SZArray = new PrimitiveType(0x1D);
  3754. internal static readonly PrimitiveType MVar = new PrimitiveType(0x1E);
  3755. internal static readonly PrimitiveType ValueType = new PrimitiveType(0x11, "ValueType", 18);
  3756. public static readonly PrimitiveType NativeInt = IntPtr;
  3757. public static readonly PrimitiveType NativeUInt = UIntPtr;
  3758. internal PrimitiveType(byte typeIx) : base(typeIx) { }
  3759. internal PrimitiveType(byte typeIx, string name, int STIx) : base(typeIx)
  3760. {
  3761. this.name = name;
  3762. this.systemTypeIndex = STIx;
  3763. }
  3764. internal string GetName() { return name; }
  3765. internal int GetSystemTypeIx() { return systemTypeIndex; }
  3766. internal sealed override void TypeSig(MemoryStream str)
  3767. {
  3768. str.WriteByte(typeIndex);
  3769. }
  3770. internal override MetaDataElement GetTypeSpec(MetaData md)
  3771. {
  3772. TypeSpec tS = md.GetPrimitiveTypeSpec(systemTypeIndex);
  3773. if (tS == null) {
  3774. tS = new TypeSpec(this,md);
  3775. md.SetPrimitiveTypeSpec(systemTypeIndex,tS);
  3776. md.AddToTable(MDTable.TypeSpec,tS);
  3777. }
  3778. return tS;
  3779. }
  3780. }
  3781. /**************************************************************************/
  3782. /// <summary>
  3783. /// Descriptor for an pointer (type * or type &)
  3784. /// </summary>
  3785. public abstract class PtrType : Type {
  3786. Type baseType;
  3787. internal PtrType(Type bType, byte typeIx) : base(typeIx)
  3788. {
  3789. baseType = bType;
  3790. tabIx = MDTable.TypeSpec;
  3791. }
  3792. internal sealed override void TypeSig(MemoryStream str)
  3793. {
  3794. str.WriteByte(typeIndex);
  3795. baseType.TypeSig(str);
  3796. }
  3797. }
  3798. /**************************************************************************/
  3799. /// <summary>
  3800. /// Descriptor for a managed pointer (type & or byref)
  3801. /// </summary>
  3802. public class ManagedPointer : PtrType {
  3803. /// <summary>
  3804. /// Create new managed pointer to baseType
  3805. /// </summary>
  3806. /// <param name="bType">the base type of the pointer</param>
  3807. public ManagedPointer(Type baseType) : base(baseType,0x10) { }
  3808. }
  3809. /**************************************************************************/
  3810. /// <summary>
  3811. /// Descriptor for an unmanaged pointer (type *)
  3812. /// </summary>
  3813. public class UnmanagedPointer : PtrType {
  3814. /// <summary>
  3815. /// Create a new unmanaged pointer to baseType
  3816. /// </summary>
  3817. /// <param name="baseType">the base type of the pointer</param>
  3818. public UnmanagedPointer(Type baseType) : base(baseType, 0x0F) { }
  3819. }
  3820. /**************************************************************************/
  3821. public interface IExternRef {
  3822. ClassRef AddClass(string nsName, string name);
  3823. ClassRef AddValueClass(string nsName, string name);
  3824. }
  3825. /// <summary>
  3826. /// A reference to an external assembly (.assembly extern)
  3827. /// </summary>
  3828. public class AssemblyRef : ResolutionScope, IExternRef {
  3829. private ushort major, minor, build, revision;
  3830. uint flags, keyIx, hashIx, cultIx;
  3831. bool hasVersion = false, isKeyToken = false;
  3832. byte[] keyBytes;
  3833. string culture;
  3834. internal AssemblyRef(MetaData md, string name) : base(name,md)
  3835. {
  3836. tabIx = MDTable.AssemblyRef;
  3837. }
  3838. public void AddAssemblyAttr (AssemAttr aa)
  3839. {
  3840. flags |= (uint)aa;
  3841. }
  3842. /// <summary>
  3843. /// Add version information about this external assembly
  3844. /// </summary>
  3845. /// <param name="majVer">Major Version</param>
  3846. /// <param name="minVer">Minor Version</param>
  3847. /// <param name="bldNo">Build Number</param>
  3848. /// <param name="revNo">Revision Number</param>
  3849. public void AddVersionInfo(int majVer, int minVer, int bldNo, int revNo)
  3850. {
  3851. major = (ushort)majVer;
  3852. minor = (ushort)minVer;
  3853. build = (ushort)bldNo;
  3854. revision = (ushort)revNo;
  3855. hasVersion = true;
  3856. }
  3857. /// <summary>
  3858. /// Add the hash value for this external assembly
  3859. /// </summary>
  3860. /// <param name="hash">bytes of the hash value</param>
  3861. public void AddHash(byte[] hash)
  3862. {
  3863. hashIx = metaData.AddToBlobHeap(hash);
  3864. }
  3865. /// <summary>
  3866. /// Set the culture for this external assembly
  3867. /// </summary>
  3868. /// <param name="cult">the culture string</param>
  3869. public void AddCulture(string cult)
  3870. {
  3871. cultIx = metaData.AddToStringsHeap(cult);
  3872. culture = cult;
  3873. }
  3874. /// <summary>
  3875. /// Add the full public key for this external assembly
  3876. /// </summary>
  3877. /// <param name="key">bytes of the public key</param>
  3878. public void AddKey(byte[] key)
  3879. {
  3880. flags |= 0x0001; // full public key
  3881. keyBytes = key;
  3882. keyIx = metaData.AddToBlobHeap(key);
  3883. }
  3884. /// <summary>
  3885. /// Add the public key token (low 8 bytes of the public key)
  3886. /// </summary>
  3887. /// <param name="key">low 8 bytes of public key</param>
  3888. public void AddKeyToken(byte[] key)
  3889. {
  3890. keyIx = metaData.AddToBlobHeap(key);
  3891. keyBytes = key;
  3892. isKeyToken = true;
  3893. }
  3894. /// <summary>
  3895. /// Add a class to this external assembly
  3896. /// </summary>
  3897. /// <param name="nsName">name space name</param>
  3898. /// <param name="name">class name</param>
  3899. /// <returns></returns>
  3900. public virtual ClassRef AddClass(string nsName, string name)
  3901. {
  3902. ClassRef aClass = new ClassRef(nsName,name,metaData);
  3903. metaData.AddToTable(MDTable.TypeRef,aClass);
  3904. aClass.SetParent(this);
  3905. return aClass;
  3906. }
  3907. /// <summary>
  3908. /// Add a value class to this external assembly
  3909. /// </summary>
  3910. /// <param name="nsName">name space name</param>
  3911. /// <param name="name">class name</param>
  3912. /// <returns></returns>
  3913. public virtual ClassRef AddValueClass(string nsName, string name)
  3914. {
  3915. ClassRef aClass = new ClassRef(nsName,name,metaData);
  3916. metaData.AddToTable(MDTable.TypeRef,aClass);
  3917. aClass.SetParent(this);
  3918. aClass.MakeValueClass(ValueClass.ValueType);
  3919. return aClass;
  3920. }
  3921. internal string TypeName()
  3922. {
  3923. string result = name;
  3924. if (hasVersion)
  3925. result = result + ", Version=" + major + "." + minor + "." +
  3926. build + "." + revision;
  3927. if (keyBytes != null) {
  3928. string tokenStr = "=";
  3929. if (isKeyToken) tokenStr = "Token=";
  3930. result = result + ", PublicKey" + tokenStr;
  3931. for (int i=0; i < keyBytes.Length; i++) {
  3932. result = result + Hex.Byte(keyBytes[i]);
  3933. }
  3934. }
  3935. if (culture != null)
  3936. result = result + ", Culture=" + culture;
  3937. return result;
  3938. }
  3939. internal sealed override uint Size(MetaData md)
  3940. {
  3941. return 12 + 2 * md.StringsIndexSize() + 2 * md.BlobIndexSize();
  3942. }
  3943. internal sealed override void Write(FileImage output)
  3944. {
  3945. output.Write(major);
  3946. output.Write(minor);
  3947. output.Write(build);
  3948. output.Write(revision);
  3949. output.Write(flags);
  3950. output.BlobIndex(keyIx);
  3951. output.StringsIndex(nameIx);
  3952. output.StringsIndex(cultIx);
  3953. output.BlobIndex(hashIx);
  3954. }
  3955. internal sealed override uint GetCodedIx(CIx code)
  3956. {
  3957. switch (code) {
  3958. case (CIx.ResolutionScope) : return 2;
  3959. case (CIx.HasCustomAttr) : return 15;
  3960. case (CIx.Implementation) : return 1;
  3961. }
  3962. return 0;
  3963. }
  3964. }
  3965. /**************************************************************************/
  3966. /// <summary>
  3967. /// Descriptor for a class defined in System (mscorlib)
  3968. /// </summary>
  3969. internal class SystemClass : ClassRef {
  3970. PrimitiveType elemType;
  3971. internal SystemClass(PrimitiveType eType, AssemblyRef paren, MetaData md)
  3972. : base("System",eType.GetName(),md) {
  3973. elemType = eType;
  3974. parent = paren;
  3975. }
  3976. internal override sealed MetaDataElement GetTypeSpec(MetaData md)
  3977. {
  3978. if (typeSpec == null) typeSpec = (TypeSpec)elemType.GetTypeSpec(md);
  3979. return typeSpec;
  3980. }
  3981. internal sealed override void TypeSig(MemoryStream str)
  3982. {
  3983. str.WriteByte(elemType.GetTypeIndex());
  3984. }
  3985. }
  3986. /**************************************************************************/
  3987. /// <summary>
  3988. /// The assembly for mscorlib.
  3989. /// </summary>
  3990. public sealed class MSCorLib : AssemblyRef {
  3991. private static readonly int valueTypeIx = 18;
  3992. private readonly string systemName = "System";
  3993. private Class[] systemClasses = new Class[valueTypeIx+2];
  3994. private PrimitiveType[] systemTypes = new PrimitiveType[valueTypeIx];
  3995. private TypeSpec[] specialTypeSpecs = new TypeSpec[valueTypeIx];
  3996. private static int[] specialNames = {
  3997. PrimitiveType.Void.GetName().GetHashCode(),
  3998. PrimitiveType.Boolean.GetName().GetHashCode(),
  3999. PrimitiveType.Char.GetName().GetHashCode(),
  4000. PrimitiveType.Int8.GetName().GetHashCode(),
  4001. PrimitiveType.UInt8.GetName().GetHashCode(),
  4002. PrimitiveType.Int16.GetName().GetHashCode(),
  4003. PrimitiveType.UInt16.GetName().GetHashCode(),
  4004. PrimitiveType.Int32.GetName().GetHashCode(),
  4005. PrimitiveType.UInt32.GetName().GetHashCode(),
  4006. PrimitiveType.Int64.GetName().GetHashCode(),
  4007. PrimitiveType.UInt64.GetName().GetHashCode(),
  4008. PrimitiveType.Float32.GetName().GetHashCode(),
  4009. PrimitiveType.Float64.GetName().GetHashCode(),
  4010. PrimitiveType.String.GetName().GetHashCode(),
  4011. PrimitiveType.TypedRef.GetName().GetHashCode(),
  4012. PrimitiveType.IntPtr.GetName().GetHashCode(),
  4013. PrimitiveType.UIntPtr.GetName().GetHashCode(),
  4014. PrimitiveType.Object.GetName().GetHashCode(),
  4015. PrimitiveType.ValueType.GetName ().GetHashCode(),
  4016. "Enum".GetHashCode()
  4017. };
  4018. internal MSCorLib(MetaData md) : base(md,"mscorlib")
  4019. {
  4020. if (!PEFile.IsMSCorlib)
  4021. md.AddToTable(MDTable.AssemblyRef,this);
  4022. systemTypes[PrimitiveType.Void.GetSystemTypeIx()] = PrimitiveType.Void;
  4023. systemTypes[PrimitiveType.Boolean.GetSystemTypeIx()] = PrimitiveType.Boolean;
  4024. systemTypes[PrimitiveType.Char.GetSystemTypeIx()] = PrimitiveType.Char;
  4025. systemTypes[PrimitiveType.Int8.GetSystemTypeIx()] = PrimitiveType.Int8;
  4026. systemTypes[PrimitiveType.UInt8.GetSystemTypeIx()] = PrimitiveType.UInt8;
  4027. systemTypes[PrimitiveType.Int16.GetSystemTypeIx()] = PrimitiveType.Int16;
  4028. systemTypes[PrimitiveType.UInt16.GetSystemTypeIx()] = PrimitiveType.UInt16;
  4029. systemTypes[PrimitiveType.Int32.GetSystemTypeIx()] = PrimitiveType.Int32;
  4030. systemTypes[PrimitiveType.UInt32.GetSystemTypeIx()] = PrimitiveType.UInt32;
  4031. systemTypes[PrimitiveType.Int64.GetSystemTypeIx()] = PrimitiveType.Int64;
  4032. systemTypes[PrimitiveType.UInt64.GetSystemTypeIx()] = PrimitiveType.UInt64;
  4033. systemTypes[PrimitiveType.Float32.GetSystemTypeIx()] = PrimitiveType.Float32;
  4034. systemTypes[PrimitiveType.Float64.GetSystemTypeIx()] = PrimitiveType.Float64;
  4035. systemTypes[PrimitiveType.IntPtr.GetSystemTypeIx()] = PrimitiveType.IntPtr;
  4036. systemTypes[PrimitiveType.UIntPtr.GetSystemTypeIx()] = PrimitiveType.UIntPtr;
  4037. systemTypes[PrimitiveType.String.GetSystemTypeIx()] = PrimitiveType.String;
  4038. systemTypes[PrimitiveType.Object.GetSystemTypeIx()] = PrimitiveType.Object;
  4039. systemTypes[PrimitiveType.TypedRef.GetSystemTypeIx()] = PrimitiveType.TypedRef;
  4040. }
  4041. /// <summary>
  4042. /// Add a class to the mscorlib assembly
  4043. /// </summary>
  4044. /// <param name="nsName">name space name</param>
  4045. /// <param name="name">class name</param>
  4046. /// <returns></returns>
  4047. public override ClassRef AddClass(string nsName, string name)
  4048. {
  4049. /* This gets called by !mscorlib, for adding references INTO mscorlib, so
  4050. it should be returning ClassRef ..*/
  4051. Class aClass = GetSpecialClass(nsName,name);
  4052. if (aClass == null) {
  4053. aClass = new ClassRef(nsName,name,metaData);
  4054. metaData.AddToTable(MDTable.TypeRef,aClass);
  4055. if (aClass is ClassRef)
  4056. ((ClassRef) aClass).SetParent(this);
  4057. }
  4058. //FIXME: Check for !ClassRef here?
  4059. return (ClassRef) aClass;
  4060. }
  4061. private Class GetSpecialClass(string nsName,string name)
  4062. {
  4063. if (nsName.CompareTo(systemName) != 0) return null;
  4064. int hash = name.GetHashCode();
  4065. for (int i=0; i < specialNames.Length; i++) {
  4066. if (hash != specialNames[i])
  4067. continue;
  4068. if (systemClasses[i] == null) {
  4069. if (i < valueTypeIx) {
  4070. systemClasses[i] = new SystemClass(systemTypes[i],this,metaData);
  4071. if ((systemTypes[i] != PrimitiveType.Object) &&
  4072. (systemTypes[i] != PrimitiveType.String)) {
  4073. systemClasses[i].MakeValueClass(ValueClass.ValueType);
  4074. }
  4075. } else {
  4076. systemClasses[i] = new ClassRef(nsName,name,metaData);
  4077. ((ClassRef) systemClasses[i]).SetParent(this);
  4078. if (!ClassDef.IsValueType (nsName, name) && !ClassDef.IsEnum (nsName, name))
  4079. systemClasses[i].MakeValueClass(ValueClass.ValueType);
  4080. }
  4081. metaData.AddToTable(MDTable.TypeRef,systemClasses[i]);
  4082. }
  4083. return systemClasses[i];
  4084. }
  4085. return null;
  4086. }
  4087. internal void SetSpecialSystemClass (string nsName, string name, Class aClass)
  4088. {
  4089. if (nsName != systemName) return;
  4090. int hash = name.GetHashCode ();
  4091. for (int i = 0; i < specialNames.Length; i++) {
  4092. if (hash != specialNames [i])
  4093. continue;
  4094. if (systemClasses [i] == null) {
  4095. systemClasses [i] = aClass;
  4096. }
  4097. }
  4098. }
  4099. internal Class GetSpecialSystemClass(PrimitiveType pType)
  4100. {
  4101. int ix = pType.GetSystemTypeIx();
  4102. if (systemClasses[ix] == null && !PEFile.IsMSCorlib) {
  4103. systemClasses[ix] = new SystemClass(pType,this,metaData);
  4104. metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
  4105. }
  4106. return systemClasses[ix];
  4107. }
  4108. private ClassRef GetValueClass(string name, int hash)
  4109. {
  4110. /* Called by MSCorLib.AddValueClass, which is called by
  4111. !mscorlib, for adding ref to value class INTO mscorlib,
  4112. so this should be classref */
  4113. int ix = valueTypeIx;
  4114. if (hash != specialNames[valueTypeIx]) ix++;
  4115. if (systemClasses[ix] == null) {
  4116. systemClasses[ix] = new ClassRef(systemName,name,metaData);
  4117. ((ClassRef) systemClasses[ix]).SetParent(this);
  4118. ((ClassRef) systemClasses[ix]).MakeValueClass(ValueClass.ValueType);
  4119. metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
  4120. }
  4121. return (ClassRef) systemClasses[ix];
  4122. }
  4123. internal Class ValueType()
  4124. {
  4125. if (systemClasses[valueTypeIx] == null && !PEFile.IsMSCorlib) {
  4126. ClassRef valType = new ClassRef("System","ValueType",metaData);
  4127. valType.SetParent(this);
  4128. valType.MakeValueClass(ValueClass.ValueType);
  4129. metaData.AddToTable(MDTable.TypeRef,valType);
  4130. systemClasses[valueTypeIx] = valType;
  4131. }
  4132. return systemClasses[valueTypeIx];
  4133. }
  4134. internal Class EnumType()
  4135. {
  4136. /* Called by both mscorlib & !mscorlib, so can be
  4137. either ClassRef or ClassDef */
  4138. //systemClasses [ valueTypeIx + 1] -> System.Enum
  4139. if (systemClasses[valueTypeIx + 1] == null && !PEFile.IsMSCorlib) {
  4140. ClassRef valType = new ClassRef("System","Enum",metaData);
  4141. valType.SetParent(this);
  4142. valType.MakeValueClass(ValueClass.Enum);
  4143. metaData.AddToTable(MDTable.TypeRef,valType);
  4144. systemClasses[valueTypeIx + 1] = valType;
  4145. }
  4146. return systemClasses[valueTypeIx + 1];
  4147. }
  4148. /// <summary>
  4149. /// Add a value class to this external assembly
  4150. /// </summary>
  4151. /// <param name="nsName">name space name</param>
  4152. /// <param name="name">class name</param>
  4153. /// <returns></returns>
  4154. public override ClassRef AddValueClass(string nsName, string name)
  4155. {
  4156. if (nsName.CompareTo(systemName) == 0) {
  4157. int hash = name.GetHashCode();
  4158. if ((hash == specialNames[valueTypeIx]) ||
  4159. (hash == specialNames[valueTypeIx+1])) {
  4160. return GetValueClass(name,hash);
  4161. }
  4162. }
  4163. ClassRef aClass = new ClassRef(nsName,name,metaData);
  4164. metaData.AddToTable(MDTable.TypeRef,aClass);
  4165. aClass.SetParent(this);
  4166. aClass.MakeValueClass(ValueClass.ValueType);
  4167. return aClass;
  4168. }
  4169. }
  4170. /**************************************************************************/
  4171. /// <summary>
  4172. /// MetaData
  4173. /// Root (20 bytes + UTF-8 Version String + quad align padding)
  4174. /// StreamHeaders (8 bytes + null terminated name string + quad align padding)
  4175. /// Streams
  4176. /// #~ (always present - holds metadata tables)
  4177. /// #Strings (always present - holds identifier strings)
  4178. /// #US (Userstring heap)
  4179. /// #Blob (signature blobs)
  4180. /// #GUID (guids for assemblies or Modules)
  4181. /// </summary>
  4182. public class MetaData {
  4183. internal static readonly int[] CIxShiftMap = {2,2,5,1,2,3,1,1,1,2,3,2,1};
  4184. private static readonly byte StringsHeapMask = 0x1;
  4185. private static readonly byte GUIDHeapMask = 0x2;
  4186. private static readonly byte BlobHeapMask = 0x4;
  4187. private static readonly uint MetaDataSignature = 0x424A5342;
  4188. private static readonly uint maxSmlIxSize = 0xFFFF;
  4189. private static readonly uint max1BitSmlIx = 0x7FFF;
  4190. private static readonly uint max2BitSmlIx = 0x3FFF;
  4191. private static readonly uint max3BitSmlIx = 0x1FFF;
  4192. private static readonly uint max5BitSmlIx = 0x7FF;
  4193. // NOTE: version and stream name strings MUST always be quad padded
  4194. #if NET_2_0 || BOOTSTRAP_NET_2_0
  4195. private static readonly string version = "v2.0.50727\0\0";
  4196. #else
  4197. private static readonly string version = "v1.1.4322\0\0\0";
  4198. #endif
  4199. private static readonly char[] tildeName = {'#','~','\0','\0'};
  4200. private static readonly char[] stringsName = {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'};
  4201. private static readonly char[] usName = {'#','U','S','\0'};
  4202. private static readonly char[] guidName = {'#','G','U','I','D','\0','\0','\0'};
  4203. private static readonly char[] blobName = {'#','B','l','o','b','\0','\0','\0'};
  4204. private static readonly uint MetaDataHeaderSize = 20 + (uint)version.Length;
  4205. private static readonly uint TildeHeaderSize = 24;
  4206. private static readonly uint StreamHeaderSize = 8;
  4207. private static readonly uint numMetaDataTables = (int)MDTable.GenericParamConstraint + 1;
  4208. private static readonly uint tildeHeaderSize = 8 + (uint)tildeName.Length;
  4209. MetaDataStream strings, us, guid, blob;
  4210. MetaDataStream[] streams = new MetaDataStream[5];
  4211. uint numStreams = 5;
  4212. uint tildeTide = 0, tildePadding = 0, tildeStart = 0;
  4213. uint numTables = 0, resourcesSize = 0;
  4214. ArrayList[] metaDataTables = new ArrayList[numMetaDataTables];
  4215. ArrayList byteCodes = new ArrayList();
  4216. uint codeSize = 0, codeStart, byteCodePadding = 0, metaDataSize = 0;
  4217. ulong valid = 0, /*sorted = 0x000002003301FA00;*/ sorted = 0;
  4218. bool[] largeIx = new bool[numMetaDataTables];
  4219. bool[] lgeCIx = new bool[(int)CIx.MaxCIx];
  4220. bool largeStrings = false, largeUS = false, largeGUID = false, largeBlob = false;
  4221. private FileImage file;
  4222. private byte heapSizes = 0;
  4223. MetaDataElement entryPoint;
  4224. BinaryWriter output;
  4225. public MSCorLib mscorlib;
  4226. private TypeSpec[] systemTypeSpecs = new TypeSpec[PrimitiveType.NumSystemTypes];
  4227. long mdStart;
  4228. private ArrayList cattr_list;
  4229. private ArrayList declsec_list;
  4230. ArrayList resources;
  4231. internal MetaData(FileImage file)
  4232. {
  4233. // tilde = new MetaDataStream(tildeName,false,0);
  4234. this.file = file;
  4235. strings = new MetaDataStream(stringsName,new UTF8Encoding(),true);
  4236. us = new MetaDataStream(usName,new UnicodeEncoding(),true);
  4237. guid = new MetaDataStream(guidName,false);
  4238. blob = new MetaDataStream(blobName,true);
  4239. streams[1] = strings;
  4240. streams[2] = us;
  4241. streams[3] = guid;
  4242. streams[4] = blob;
  4243. for (int i=0; i < numMetaDataTables; i++) {
  4244. largeIx[i] = false;
  4245. }
  4246. for (int i=0; i < lgeCIx.Length; i++) {
  4247. lgeCIx[i] = false;
  4248. }
  4249. mscorlib = new MSCorLib(this);
  4250. }
  4251. internal TypeSpec GetPrimitiveTypeSpec(int ix)
  4252. {
  4253. return systemTypeSpecs[ix];
  4254. }
  4255. internal void SetPrimitiveTypeSpec(int ix, TypeSpec typeSpec)
  4256. {
  4257. systemTypeSpecs[ix] = typeSpec;
  4258. }
  4259. internal uint Size()
  4260. {
  4261. return metaDataSize;
  4262. }
  4263. private void CalcHeapSizes ()
  4264. {
  4265. if (strings.LargeIx()) {
  4266. largeStrings = true;
  4267. heapSizes |= StringsHeapMask;
  4268. }
  4269. if (guid.LargeIx()) {
  4270. largeGUID = true;
  4271. heapSizes |= GUIDHeapMask;
  4272. }
  4273. if (blob.LargeIx()) {
  4274. largeBlob = true;
  4275. heapSizes |= BlobHeapMask;
  4276. }
  4277. largeUS = us.LargeIx();
  4278. }
  4279. internal void StreamSize(byte mask)
  4280. {
  4281. heapSizes |= mask;
  4282. }
  4283. internal uint AddToUSHeap(string str)
  4284. {
  4285. if (str == null) return 0;
  4286. return us.Add(str,true);
  4287. }
  4288. internal uint AddToUSHeap(byte[] str)
  4289. {
  4290. if (str == null) return 0;
  4291. return us.Add (str, true);
  4292. }
  4293. internal uint AddToStringsHeap(string str)
  4294. {
  4295. if ((str == null) || (str.CompareTo("") == 0)) return 0;
  4296. return strings.Add(str,false);
  4297. }
  4298. internal uint AddToGUIDHeap(Guid guidNum)
  4299. {
  4300. return guid.Add(guidNum, false);
  4301. }
  4302. internal uint AddToBlobHeap(byte[] blobBytes)
  4303. {
  4304. if (blobBytes == null) return 0;
  4305. return blob.Add(blobBytes, true);
  4306. }
  4307. internal uint AddToBlobHeap(byte val)
  4308. {
  4309. return blob.Add(val, true);
  4310. }
  4311. internal uint AddToBlobHeap(sbyte val)
  4312. {
  4313. return blob.Add(val, true);
  4314. }
  4315. internal uint AddToBlobHeap(ushort val)
  4316. {
  4317. return blob.Add(val, true);
  4318. }
  4319. internal uint AddToBlobHeap(short val)
  4320. {
  4321. return blob.Add(val, true);
  4322. }
  4323. internal uint AddToBlobHeap(uint val)
  4324. {
  4325. return blob.Add(val, true);
  4326. }
  4327. internal uint AddToBlobHeap(int val)
  4328. {
  4329. return blob.Add(val, true);
  4330. }
  4331. internal uint AddToBlobHeap(ulong val)
  4332. {
  4333. return blob.Add(val, true);
  4334. }
  4335. internal uint AddToBlobHeap(long val)
  4336. {
  4337. return blob.Add(val, true);
  4338. }
  4339. internal uint AddToBlobHeap(float val)
  4340. {
  4341. return blob.Add(val, true);
  4342. }
  4343. internal uint AddToBlobHeap(double val)
  4344. {
  4345. return blob.Add(val, true);
  4346. }
  4347. internal uint AddToBlobHeap(string val)
  4348. {
  4349. return blob.Add(val,true);
  4350. }
  4351. internal void AddCustomAttribute (CustomAttribute cattr)
  4352. {
  4353. if (cattr_list == null)
  4354. cattr_list = new ArrayList ();
  4355. cattr_list.Add (cattr);
  4356. }
  4357. internal void AddDeclSecurity (BaseDeclSecurity decl_sec)
  4358. {
  4359. if (declsec_list == null)
  4360. declsec_list = new ArrayList ();
  4361. declsec_list.Add (decl_sec);
  4362. }
  4363. private ArrayList GetTable(MDTable tableIx)
  4364. {
  4365. int tabIx = (int)tableIx;
  4366. if (metaDataTables[tabIx] == null) {
  4367. metaDataTables[tabIx] = new ArrayList();
  4368. valid |= ((ulong)0x1 << tabIx);
  4369. // Console.WriteLine("after creating table " + tableIx + "(" + tabIx + ") valid = " + valid);
  4370. numTables++;
  4371. }
  4372. return metaDataTables[tabIx];
  4373. }
  4374. internal void AddToTable(MDTable tableIx, MetaDataElement elem)
  4375. {
  4376. if (elem.Row > 0) {
  4377. // Console.Out.WriteLine("ERROR - element already in table " + tableIx);
  4378. return;
  4379. }
  4380. // updates Row field of the element
  4381. // Console.WriteLine("Adding element to table " + (uint)tableIx);
  4382. ArrayList table = GetTable(tableIx);
  4383. elem.Row = (uint)table.Count + 1;
  4384. table.Add(elem);
  4385. }
  4386. internal uint TableIndex(MDTable tableIx)
  4387. {
  4388. if (metaDataTables[(int)tableIx] == null) return 1;
  4389. return (uint)metaDataTables[(int)tableIx].Count+1;
  4390. }
  4391. internal uint AddCode(CILInstructions byteCode)
  4392. {
  4393. byteCodes.Add(byteCode);
  4394. uint offset = codeSize + codeStart;
  4395. codeSize += byteCode.GetCodeSize();
  4396. return offset;
  4397. }
  4398. internal void SetEntryPoint(MetaDataElement ep)
  4399. {
  4400. entryPoint = ep;
  4401. }
  4402. internal uint AddResource(byte[] resBytes)
  4403. {
  4404. if (resources == null) resources = new ArrayList ();
  4405. resources.Add (resBytes);
  4406. uint offset = resourcesSize;
  4407. resourcesSize += (uint)resBytes.Length + 4;
  4408. return offset;
  4409. }
  4410. internal void AddData(DataConstant cVal)
  4411. {
  4412. file.AddInitData(cVal);
  4413. }
  4414. internal static void CompressNum(uint val, MemoryStream sig)
  4415. {
  4416. if (val <= 0x7F) {
  4417. sig.WriteByte((byte)val);
  4418. } else if (val <= 0x3FFF) {
  4419. byte b1 = (byte)((val >> 8) | 0x80);
  4420. byte b2 = (byte)(val & FileImage.iByteMask[0]);
  4421. sig.WriteByte(b1);
  4422. sig.WriteByte(b2);
  4423. } else {
  4424. byte b1 = (byte)((val >> 24) | 0xC0);
  4425. byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
  4426. byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
  4427. byte b4 = (byte)(val & FileImage.iByteMask[0]);
  4428. sig.WriteByte(b1);
  4429. sig.WriteByte(b2);
  4430. sig.WriteByte(b3);
  4431. sig.WriteByte(b4);
  4432. }
  4433. }
  4434. internal uint CodeSize()
  4435. {
  4436. return codeSize + byteCodePadding;
  4437. }
  4438. internal uint GetResourcesSize()
  4439. {
  4440. return resourcesSize;
  4441. }
  4442. internal uint StringsIndexSize()
  4443. {
  4444. if (largeStrings) return 4;
  4445. return 2;
  4446. }
  4447. internal uint GUIDIndexSize()
  4448. {
  4449. if (largeGUID) return 4;
  4450. return 2;
  4451. }
  4452. internal uint USIndexSize()
  4453. {
  4454. if (largeUS) return 4;
  4455. return 2;
  4456. }
  4457. internal uint BlobIndexSize()
  4458. {
  4459. if (largeBlob) return 4;
  4460. return 2;
  4461. }
  4462. internal uint CodedIndexSize(CIx code)
  4463. {
  4464. if (lgeCIx[(uint)code]) return 4;
  4465. return 2;
  4466. }
  4467. internal uint TableIndexSize(MDTable tabIx)
  4468. {
  4469. if (largeIx[(uint)tabIx]) return 4;
  4470. return 2;
  4471. }
  4472. private void SetIndexSizes()
  4473. {
  4474. for (int i=0; i < numMetaDataTables; i++) {
  4475. if (metaDataTables[i] == null)
  4476. continue;
  4477. uint count = (uint)metaDataTables[i].Count;
  4478. if (count > maxSmlIxSize)
  4479. largeIx[i] = true;
  4480. MDTable tabIx = (MDTable)i;
  4481. if (count > max5BitSmlIx) {
  4482. lgeCIx[(int)CIx.HasCustomAttr] = true;
  4483. }
  4484. if (count > max3BitSmlIx) {
  4485. if ((tabIx == MDTable.TypeRef) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.Method) || (tabIx == MDTable.TypeSpec) || (tabIx == MDTable.Field))
  4486. lgeCIx[(int)CIx.CustomAttributeType] = true;
  4487. if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
  4488. lgeCIx[(int)CIx.MemberRefParent] = true;
  4489. }
  4490. if (count > max2BitSmlIx) {
  4491. if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param) || (tabIx == MDTable.Property))
  4492. lgeCIx[(int)CIx.HasConst] = true;
  4493. if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.TypeRef) || (tabIx == MDTable.TypeSpec))
  4494. lgeCIx[(int)CIx.TypeDefOrRef] = true;
  4495. if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method) || (tabIx == MDTable.Assembly))
  4496. lgeCIx[(int)CIx.HasDeclSecurity] = true;
  4497. if ((tabIx == MDTable.File) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.ExportedType))
  4498. lgeCIx[(int)CIx.Implementation] = true;
  4499. if ((tabIx == MDTable.Module) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.TypeRef))
  4500. lgeCIx[(int)CIx.ResolutionScope] = true;
  4501. }
  4502. if (count > max1BitSmlIx) {
  4503. if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param))
  4504. lgeCIx[(int)CIx.HasFieldMarshal] = true;
  4505. if ((tabIx == MDTable.Event) || (tabIx == MDTable.Property))
  4506. lgeCIx[(int)CIx.HasSemantics] = true;
  4507. if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
  4508. lgeCIx[(int)CIx.MethodDefOrRef] = true;
  4509. if ((tabIx == MDTable.Field) || (tabIx == MDTable.Method))
  4510. lgeCIx[(int)CIx.MemberForwarded] = true;
  4511. if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method))
  4512. lgeCIx[(int)CIx.TypeOrMethodDef] = true;
  4513. }
  4514. }
  4515. }
  4516. private void SetStreamOffsets()
  4517. {
  4518. uint sizeOfHeaders = StreamHeaderSize + (uint)tildeName.Length;
  4519. for (int i=1; i < numStreams; i++) {
  4520. sizeOfHeaders += streams[i].headerSize();
  4521. }
  4522. metaDataSize = MetaDataHeaderSize + sizeOfHeaders;
  4523. tildeStart = metaDataSize;
  4524. metaDataSize += tildeTide + tildePadding;
  4525. for (int i=1; i < numStreams; i++) {
  4526. streams[i].Start = metaDataSize;
  4527. metaDataSize += streams[i].Size();
  4528. streams[i].WriteDetails();
  4529. }
  4530. }
  4531. internal void CalcTildeStreamSize()
  4532. {
  4533. CalcHeapSizes ();
  4534. //tilde.SetIndexSizes(strings.LargeIx(),us.LargeIx(),guid.LargeIx(),blob.LargeIx());
  4535. tildeTide = TildeHeaderSize;
  4536. tildeTide += 4 * numTables;
  4537. //Console.WriteLine("Tilde header + sizes = " + tildeTide);
  4538. for (int i=0; i < numMetaDataTables; i++) {
  4539. if (metaDataTables[i] != null) {
  4540. ArrayList table = metaDataTables[i];
  4541. // Console.WriteLine("Meta data table " + i + " at offset " + tildeTide);
  4542. tildeTide += (uint)table.Count * ((MetaDataElement)table[0]).Size(this);
  4543. // Console.WriteLine("Metadata table " + i + " has size " + table.Count);
  4544. // Console.WriteLine("tildeTide = " + tildeTide);
  4545. }
  4546. }
  4547. if ((tildeTide % 4) != 0) tildePadding = 4 - (tildeTide % 4);
  4548. //Console.WriteLine("tildePadding = " + tildePadding);
  4549. }
  4550. internal void WriteTildeStream(FileImage output)
  4551. {
  4552. long startTilde = output.Seek(0,SeekOrigin.Current);
  4553. output.Write((uint)0); // Reserved
  4554. #if NET_2_0 || BOOTSTRAP_NET_2_0
  4555. output.Write((byte)2); // MajorVersion
  4556. output.Write((byte)0); // MinorVersion
  4557. #else
  4558. output.Write((byte)1); // MajorVersion
  4559. output.Write((byte)0); // MinorVersion
  4560. #endif
  4561. output.Write(heapSizes);
  4562. output.Write((byte)1); // Reserved
  4563. output.Write(valid);
  4564. output.Write(sorted);
  4565. for (int i=0; i < numMetaDataTables; i++) {
  4566. if (metaDataTables[i] != null) {
  4567. uint count = (uint)metaDataTables[i].Count;
  4568. output.Write(count);
  4569. }
  4570. }
  4571. long tabStart = output.Seek(0,SeekOrigin.Current);
  4572. // Console.WriteLine("Starting metaData tables at " + tabStart);
  4573. for (int i=0; i < numMetaDataTables; i++) {
  4574. if (metaDataTables[i] != null) {
  4575. // Console.WriteLine("Starting metaData table " + i + " at " + (output.Seek(0,SeekOrigin.Current) - startTilde));
  4576. ArrayList table = metaDataTables[i];
  4577. for (int j=0; j < table.Count; j++) {
  4578. ((MetaDataElement)table[j]).Write(output);
  4579. }
  4580. }
  4581. }
  4582. // Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));
  4583. for (int i=0; i < tildePadding; i++) output.Write((byte)0);
  4584. }
  4585. private void BuildTable(ArrayList table)
  4586. {
  4587. if (table == null) return;
  4588. for (int j=0; j < table.Count; j++) {
  4589. ((MetaDataElement)table[j]).BuildTables(this);
  4590. }
  4591. }
  4592. private void SortTable (ArrayList mTable)
  4593. {
  4594. if (mTable == null) return;
  4595. mTable.Sort();
  4596. for (int i=0; i < mTable.Count; i++) {
  4597. ((MetaDataElement)mTable[i]).Row = (uint)i+1;
  4598. }
  4599. }
  4600. internal void BuildMetaData(uint codeStartOffset)
  4601. {
  4602. codeStart = codeStartOffset;
  4603. BuildTable(metaDataTables[(int)MDTable.TypeDef]);
  4604. BuildTable(metaDataTables[(int)MDTable.TypeSpec]);
  4605. BuildTable(metaDataTables[(int)MDTable.MemberRef]);
  4606. #if NET_2_0 || BOOTSTRAP_NET_2_0
  4607. BuildTable(metaDataTables[(int)MDTable.GenericParam]);
  4608. BuildTable(metaDataTables[(int)MDTable.MethodSpec]);
  4609. BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
  4610. #endif
  4611. BuildTable(metaDataTables[(int)MDTable.ManifestResource]);
  4612. if (cattr_list != null) {
  4613. foreach (CustomAttribute cattr in cattr_list)
  4614. cattr.BuildTables (this);
  4615. }
  4616. if (declsec_list != null) {
  4617. foreach (BaseDeclSecurity decl_sec in declsec_list)
  4618. decl_sec.BuildTables (this);
  4619. }
  4620. /* for (int i=0; i < metaDataTables.Length; i++) {
  4621. ArrayList table = metaDataTables[i];
  4622. if (table != null) {
  4623. for (int j=0; j < table.Count; j++) {
  4624. ((MetaDataElement)table[j]).BuildTables(this);
  4625. }
  4626. }
  4627. }
  4628. */
  4629. SetIndexSizes();
  4630. for (int i=1; i < numStreams; i++) {
  4631. streams[i].EndStream();
  4632. }
  4633. CalcTildeStreamSize();
  4634. SetStreamOffsets();
  4635. byteCodePadding = NumToAlign(codeSize,4);
  4636. if (entryPoint != null) file.SetEntryPoint(entryPoint.Token());
  4637. // Check ordering of specific tables
  4638. // Constant, CustomAttribute, FieldMarshal, DeclSecurity, MethodSemantics
  4639. // ImplMap, GenericParam
  4640. // Need to load GenericParamConstraint AFTER GenericParam table in correct order
  4641. // The tables:
  4642. // InterfaceImpl, ClassLayout, FieldLayout, MethodImpl, FieldRVA, NestedClass
  4643. // will _ALWAYS_ be in the correct order as embedded in BuildMDTables
  4644. SortTable(metaDataTables[(int)MDTable.Constant]);
  4645. SortTable(metaDataTables[(int)MDTable.FieldMarshal]);
  4646. SortTable(metaDataTables[(int)MDTable.DeclSecurity]);
  4647. SortTable(metaDataTables[(int)MDTable.MethodSemantics]);
  4648. SortTable(metaDataTables[(int)MDTable.ImplMap]);
  4649. #if NET_2_0 || BOOTSTRAP_NET_2_0
  4650. if (metaDataTables[(int)MDTable.GenericParam] != null) {
  4651. SortTable(metaDataTables[(int)MDTable.GenericParam]);
  4652. // Now add GenericParamConstraints
  4653. /*for (int i=0; i < metaDataTables[(int)MDTable.GenericParam].Count; i++) {
  4654. ((GenericParameter)metaDataTables[(int)MDTable.GenericParam][i]).AddConstraints(this);
  4655. }*/
  4656. }
  4657. SortTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
  4658. #endif
  4659. SortTable(metaDataTables[(int)MDTable.InterfaceImpl]);
  4660. SortTable(metaDataTables[(int)MDTable.CustomAttribute]);
  4661. }
  4662. internal void WriteByteCodes(FileImage output)
  4663. {
  4664. for (int i=0; i < byteCodes.Count; i++) {
  4665. ((CILInstructions)byteCodes[i]).Write(output);
  4666. }
  4667. for (int i=0; i < byteCodePadding; i++) {
  4668. output.Write((byte)0);
  4669. }
  4670. }
  4671. internal void WriteResources (FileImage output)
  4672. {
  4673. if (resources == null) return;
  4674. for (int i = 0; i < resources.Count; i ++) {
  4675. byte [] resBytes = (byte []) resources [i];
  4676. output.Write ((uint) resBytes.Length);
  4677. output.Write (resBytes);
  4678. }
  4679. }
  4680. internal void WriteMetaData(FileImage output)
  4681. {
  4682. this.output = output;
  4683. mdStart = output.Seek(0,SeekOrigin.Current);
  4684. // Console.WriteLine("Writing metaData at " + Hex.Long(mdStart));
  4685. output.Write(MetaDataSignature);
  4686. output.Write((short)1); // Major Version
  4687. output.Write((short)1); // Minor Version ECMA = 0, PEFiles = 1
  4688. output.Write(0); // Reserved
  4689. output.Write(version.Length);
  4690. output.Write(version.ToCharArray()); // version string is already zero padded
  4691. output.Write((short)0);
  4692. output.Write((ushort)numStreams);
  4693. // write tilde header
  4694. output.Write(tildeStart);
  4695. output.Write(tildeTide + tildePadding);
  4696. output.Write(tildeName);
  4697. for (int i=1; i < numStreams; i++) streams[i].WriteHeader(output);
  4698. // Console.WriteLine("Writing tilde stream at " + output.Seek(0,SeekOrigin.Current) + " = " + tildeStart);
  4699. WriteTildeStream(output);
  4700. for (int i=1; i < numStreams; i++) streams[i].Write(output);
  4701. // Console.WriteLine("Finished Writing metaData at " + output.Seek(0,SeekOrigin.Current));
  4702. }
  4703. internal bool LargeStringsIndex() { return strings.LargeIx(); }
  4704. internal bool LargeGUIDIndex() { return guid.LargeIx(); }
  4705. internal bool LargeUSIndex() { return us.LargeIx(); }
  4706. internal bool LargeBlobIndex() { return blob.LargeIx(); }
  4707. internal bool LargeIx(MDTable tabIx) { return largeIx[(uint)tabIx]; }
  4708. private uint NumToAlign(uint val, uint alignVal)
  4709. {
  4710. if ((val % alignVal) == 0) return 0;
  4711. return alignVal - (val % alignVal);
  4712. }
  4713. internal void WriteCodedIndex(CIx code, MetaDataElement elem, FileImage output)
  4714. {
  4715. uint ix = 0;
  4716. if (elem != null) {
  4717. ix = (elem.Row << CIxShiftMap[(uint)code]) | elem.GetCodedIx(code);
  4718. // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);
  4719. //} else {
  4720. // Console.WriteLine("elem for coded index is null");
  4721. }
  4722. if (lgeCIx[(uint)code])
  4723. output.Write(ix);
  4724. else
  4725. output.Write((ushort)ix);
  4726. }
  4727. }
  4728. /**************************************************************************/
  4729. /// <summary>
  4730. /// Stream in the Meta Data (#Strings, #US, #Blob and #GUID)
  4731. /// </summary>
  4732. internal class MetaDataStream : BinaryWriter {
  4733. private static readonly uint StreamHeaderSize = 8;
  4734. private static uint maxSmlIxSize = 0xFFFF;
  4735. private uint start = 0;
  4736. uint size = 0, tide = 1;
  4737. bool largeIx = false;
  4738. uint sizeOfHeader;
  4739. char[] name;
  4740. Hashtable htable = new Hashtable();
  4741. Hashtable btable = new Hashtable (new ByteArrayHashCodeProvider (), new ByteArrayComparer ());
  4742. internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream())
  4743. {
  4744. if (addInitByte) { Write((byte)0); size = 1; }
  4745. this.name = name;
  4746. sizeOfHeader = StreamHeaderSize + (uint)name.Length;
  4747. }
  4748. internal MetaDataStream(char[] name, System.Text.Encoding enc, bool addInitByte) : base(new MemoryStream(),enc)
  4749. {
  4750. if (addInitByte) { Write((byte)0); size = 1; }
  4751. this.name = name;
  4752. sizeOfHeader = StreamHeaderSize + (uint)name.Length;
  4753. }
  4754. public uint Start {
  4755. get { return start; }
  4756. set { start = value; }
  4757. }
  4758. internal uint headerSize()
  4759. {
  4760. // Console.WriteLine(name + " stream has headersize of " + sizeOfHeader);
  4761. return sizeOfHeader;
  4762. }
  4763. internal void SetSize(uint siz)
  4764. {
  4765. size = siz;
  4766. }
  4767. internal uint Size()
  4768. {
  4769. return size;
  4770. }
  4771. internal bool LargeIx()
  4772. {
  4773. return largeIx;
  4774. }
  4775. internal void WriteDetails()
  4776. {
  4777. // Console.WriteLine(name + " - size = " + size);
  4778. }
  4779. internal uint Add(string str, bool prependSize)
  4780. {
  4781. Object val = htable[str];
  4782. uint index = 0;
  4783. if (val == null) {
  4784. index = size;
  4785. htable[str] = index;
  4786. char[] arr = str.ToCharArray();
  4787. if (prependSize) CompressNum((uint)arr.Length*2+1);
  4788. Write(arr);
  4789. Write((byte)0);
  4790. size = (uint)Seek(0,SeekOrigin.Current);
  4791. } else {
  4792. index = (uint)val;
  4793. }
  4794. return index;
  4795. }
  4796. internal uint Add (byte[] str, bool prependSize)
  4797. {
  4798. Object val = btable [str];
  4799. uint index = 0;
  4800. if (val == null) {
  4801. index = size;
  4802. btable [str] = index;
  4803. if (prependSize) CompressNum ((uint) str.Length);
  4804. Write (str);
  4805. size = (uint) Seek (0, SeekOrigin.Current);
  4806. } else {
  4807. index = (uint) val;
  4808. }
  4809. return index;
  4810. }
  4811. internal uint Add(Guid guid, bool prependSize)
  4812. {
  4813. byte [] b = guid.ToByteArray ();
  4814. if (prependSize) CompressNum ((uint) b.Length);
  4815. Write(guid.ToByteArray());
  4816. size =(uint)Seek(0,SeekOrigin.Current);
  4817. return tide++;
  4818. }
  4819. internal uint Add(byte[] blob)
  4820. {
  4821. uint ix = size;
  4822. CompressNum((uint)blob.Length);
  4823. Write(blob);
  4824. size = (uint)Seek(0,SeekOrigin.Current);
  4825. return ix;
  4826. }
  4827. internal uint Add(byte val, bool prependSize)
  4828. {
  4829. uint ix = size;
  4830. if (prependSize) CompressNum (1);
  4831. Write(val);
  4832. size = (uint)Seek(0,SeekOrigin.Current);
  4833. return ix;
  4834. }
  4835. internal uint Add(sbyte val, bool prependSize)
  4836. {
  4837. uint ix = size;
  4838. if (prependSize) CompressNum (1);
  4839. Write(val);
  4840. size = (uint)Seek(0,SeekOrigin.Current);
  4841. return ix;
  4842. }
  4843. internal uint Add(ushort val, bool prependSize)
  4844. {
  4845. uint ix = size;
  4846. if (prependSize) CompressNum (2);
  4847. Write(val);
  4848. size = (uint)Seek(0,SeekOrigin.Current);
  4849. return ix;
  4850. }
  4851. internal uint Add(short val, bool prependSize)
  4852. {
  4853. uint ix = size;
  4854. if (prependSize) CompressNum (2);
  4855. Write(val);
  4856. size = (uint)Seek(0,SeekOrigin.Current);
  4857. return ix;
  4858. }
  4859. internal uint Add(uint val, bool prependSize)
  4860. {
  4861. uint ix = size;
  4862. if (prependSize) CompressNum (4);
  4863. Write(val);
  4864. size = (uint)Seek(0,SeekOrigin.Current);
  4865. return ix;
  4866. }
  4867. internal uint Add(int val, bool prependSize)
  4868. {
  4869. uint ix = size;
  4870. if (prependSize) CompressNum (4);
  4871. Write (val);
  4872. size = (uint)Seek(0,SeekOrigin.Current);
  4873. return ix;
  4874. }
  4875. internal uint Add(ulong val, bool prependSize)
  4876. {
  4877. uint ix = size;
  4878. if (prependSize) CompressNum (8);
  4879. Write(val);
  4880. size = (uint)Seek(0,SeekOrigin.Current);
  4881. return ix;
  4882. }
  4883. internal uint Add(long val, bool prependSize)
  4884. {
  4885. uint ix = size;
  4886. if (prependSize) CompressNum (8);
  4887. Write(val);
  4888. size = (uint)Seek(0,SeekOrigin.Current);
  4889. return ix;
  4890. }
  4891. internal uint Add(float val, bool prependSize)
  4892. {
  4893. uint ix = size;
  4894. if (prependSize) CompressNum (4);
  4895. Write(val);
  4896. size = (uint)Seek(0,SeekOrigin.Current);
  4897. return ix;
  4898. }
  4899. internal uint Add(double val, bool prependSize)
  4900. {
  4901. uint ix = size;
  4902. if (prependSize) CompressNum (8);
  4903. Write(val);
  4904. size = (uint)Seek(0,SeekOrigin.Current);
  4905. return ix;
  4906. }
  4907. private void CompressNum(uint val)
  4908. {
  4909. if (val < 0x7F) {
  4910. Write((byte)val);
  4911. } else if (val < 0x3FFF) {
  4912. byte b1 = (byte)((val >> 8) | 0x80);
  4913. byte b2 = (byte)(val & FileImage.iByteMask[0]);
  4914. Write(b1);
  4915. Write(b2);
  4916. } else {
  4917. byte b1 = (byte)((val >> 24) | 0xC0);
  4918. byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
  4919. byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
  4920. byte b4 = (byte)(val & FileImage.iByteMask[0]);
  4921. Write(b1);
  4922. Write(b2);
  4923. Write(b3);
  4924. Write(b4);
  4925. }
  4926. }
  4927. private void QuadAlign()
  4928. {
  4929. if ((size % 4) != 0) {
  4930. uint pad = 4 - (size % 4);
  4931. size += pad;
  4932. for (int i=0; i < pad; i++) {
  4933. Write((byte)0);
  4934. }
  4935. }
  4936. }
  4937. internal void EndStream()
  4938. {
  4939. QuadAlign();
  4940. if (size > maxSmlIxSize) {
  4941. largeIx = true;
  4942. }
  4943. }
  4944. internal void WriteHeader(BinaryWriter output)
  4945. {
  4946. output.Write(start);
  4947. output.Write(size);
  4948. output.Write(name);
  4949. }
  4950. internal virtual void Write(BinaryWriter output)
  4951. {
  4952. // Console.WriteLine("Writing " + name + " stream at " + output.Seek(0,SeekOrigin.Current) + " = " + start);
  4953. MemoryStream str = (MemoryStream)BaseStream;
  4954. output.Write(str.ToArray());
  4955. }
  4956. }
  4957. /**************************************************************************/
  4958. class ByteArrayComparer : IComparer {
  4959. public int Compare (object x, object y)
  4960. {
  4961. byte [] a = (byte []) x;
  4962. byte [] b = (byte []) y;
  4963. int len = a.Length;
  4964. if (b.Length != len)
  4965. return 1;
  4966. for (int i = 0; i < len; ++i)
  4967. if (a [i] != b [i])
  4968. return 1;
  4969. return 0;
  4970. }
  4971. }
  4972. class ByteArrayHashCodeProvider : IHashCodeProvider {
  4973. public int GetHashCode (Object key)
  4974. {
  4975. byte [] arr = (byte []) key;
  4976. int len = arr.Length;
  4977. int h = 0;
  4978. for (int i = 0; i < len; ++i)
  4979. h = (h << 5) - h + arr [i];
  4980. return h;
  4981. }
  4982. }
  4983. }