PEAPI.cs 235 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822
  1. using System;
  2. using System.IO;
  3. using System.Collections;
  4. using System.Text;
  5. namespace PEAPI
  6. {
  7. public class Hex {
  8. readonly static char[] hexDigit = {'0','1','2','3','4','5','6','7',
  9. '8','9','A','B','C','D','E','F'};
  10. readonly static uint[] iByteMask = {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000};
  11. readonly static ulong[] lByteMask = {0x00000000000000FF, 0x000000000000FF00,
  12. 0x0000000000FF0000, 0x00000000FF000000,
  13. 0x000000FF00000000, 0x0000FF0000000000,
  14. 0x00FF000000000000, 0xFF00000000000000 };
  15. readonly static uint nibble0Mask = 0x0000000F;
  16. readonly static uint nibble1Mask = 0x000000F0;
  17. public static String Byte(int b) {
  18. char[] str = new char[2];
  19. uint num = (uint)b;
  20. uint b1 = num & nibble0Mask;
  21. uint b2 = (num & nibble1Mask) >> 4;
  22. str[0] = hexDigit[b2];
  23. str[1] = hexDigit[b1];
  24. return new String(str);
  25. }
  26. public static String Short(int b) {
  27. char[] str = new char[4];
  28. uint num1 = (uint)b & iByteMask[0];
  29. uint num2 = ((uint)b & iByteMask[1]) >> 8;
  30. uint b1 = num1 & nibble0Mask;
  31. uint b2 = (num1 & nibble1Mask) >> 4;
  32. uint b3 = num2 & nibble0Mask;
  33. uint b4 = (num2 & nibble1Mask) >> 4;
  34. str[0] = hexDigit[b4];
  35. str[1] = hexDigit[b3];
  36. str[2] = hexDigit[b2];
  37. str[3] = hexDigit[b1];
  38. return new String(str);
  39. }
  40. public static String Int(int val) {
  41. char[] str = new char[8];
  42. uint num = (uint)val;
  43. int strIx = 7;
  44. for (int i=0; i < iByteMask.Length; i++) {
  45. uint b = num & iByteMask[i];
  46. b >>= (i*8);
  47. uint b1 = b & nibble0Mask;
  48. uint b2 = (b & nibble1Mask) >> 4;
  49. str[strIx--] = hexDigit[b1];
  50. str[strIx--] = hexDigit[b2];
  51. }
  52. return new String(str);
  53. }
  54. public static String Int(uint num) {
  55. char[] str = new char[8];
  56. int strIx = 7;
  57. for (int i=0; i < iByteMask.Length; i++) {
  58. uint b = num & iByteMask[i];
  59. b >>= (i*8);
  60. uint b1 = b & nibble0Mask;
  61. uint b2 = (b & nibble1Mask) >> 4;
  62. str[strIx--] = hexDigit[b1];
  63. str[strIx--] = hexDigit[b2];
  64. }
  65. return new String(str);
  66. }
  67. public static String Long(long lnum) {
  68. ulong num = (ulong)lnum;
  69. char[] str = new char[16];
  70. int strIx = 15;
  71. for (int i=0; i < lByteMask.Length; i++) {
  72. ulong b = num & lByteMask[i];
  73. b >>= (i*8);
  74. ulong b1 = b & nibble0Mask;
  75. ulong b2 = (b & nibble1Mask) >> 4;
  76. str[strIx--] = hexDigit[b1];
  77. str[strIx--] = hexDigit[b2];
  78. }
  79. return new String(str);
  80. }
  81. }
  82. public class NotYetImplementedException : System.Exception
  83. {
  84. public NotYetImplementedException(string msg) : base(msg + " Not Yet Implemented") { }
  85. }
  86. public class TypeSignatureException : System.Exception {
  87. public TypeSignatureException(string msg) : base(msg) { }
  88. }
  89. public class ClassRefInst : Type {
  90. private Type type;
  91. private bool is_value;
  92. public ClassRefInst (Type type, bool is_value) : base (0x12) {
  93. this.type = type;
  94. this.is_value = is_value;
  95. if (is_value)
  96. type.SetTypeIndex (0x11);
  97. tabIx = MDTable.TypeSpec;
  98. }
  99. internal sealed override void TypeSig(MemoryStream str) {
  100. type.TypeSig (str);
  101. }
  102. }
  103. public class MVar : Type {
  104. private int index;
  105. public MVar (int index) : base (0x1E) {
  106. this.index = index;
  107. tabIx = MDTable.TypeSpec;
  108. }
  109. internal sealed override void TypeSig(MemoryStream str) {
  110. str.WriteByte(typeIndex);
  111. MetaData.CompressNum ((uint) index, str);
  112. }
  113. }
  114. public class GenericTypeSpec : Type {
  115. private int index;
  116. public GenericTypeSpec (int index) : base (0x13) {
  117. this.index = index;
  118. tabIx = MDTable.TypeSpec;
  119. }
  120. internal sealed override void TypeSig(MemoryStream str) {
  121. str.WriteByte(typeIndex);
  122. MetaData.CompressNum ((uint) index, str);
  123. }
  124. }
  125. public class GenericTypeInst : Type {
  126. private Type gen_type;
  127. private Type[] gen_param;
  128. public GenericTypeInst (Type gen_type, Type[] gen_param) : base (0x15)
  129. {
  130. typeIndex = 0x15;
  131. this.gen_type = gen_type;
  132. this.gen_param = gen_param;
  133. tabIx = MDTable.TypeSpec;
  134. }
  135. internal sealed override void TypeSig(MemoryStream str) {
  136. str.WriteByte(typeIndex);
  137. gen_type.TypeSig (str);
  138. MetaData.CompressNum ((uint) gen_param.Length, str);
  139. foreach (Type param in gen_param)
  140. param.TypeSig (str);
  141. }
  142. }
  143. public class GenericMethodSig {
  144. private Type[] gen_param;
  145. public GenericMethodSig (Type[] gen_param)
  146. {
  147. this.gen_param = gen_param;
  148. }
  149. internal void TypeSig (MemoryStream str)
  150. {
  151. MetaData.CompressNum ((uint) gen_param.Length, str); // THIS IS NOT RIGHT, but works
  152. MetaData.CompressNum ((uint) gen_param.Length, str);
  153. foreach (Type param in gen_param)
  154. param.TypeSig (str);
  155. }
  156. internal uint GetSigIx (MetaData md)
  157. {
  158. MemoryStream sig = new MemoryStream();
  159. TypeSig (sig);
  160. return md.AddToBlobHeap (sig.ToArray());
  161. }
  162. }
  163. public class Sentinel : Type {
  164. public Sentinel () : base (0x41) { }
  165. internal sealed override void TypeSig(MemoryStream str) {
  166. str.WriteByte(typeIndex);
  167. }
  168. }
  169. /// <summary>
  170. /// The IL Array type
  171. /// </summary>
  172. public abstract class Array : Type
  173. {
  174. protected Type elemType;
  175. protected MetaData metaData;
  176. protected string cnameSpace, cname;
  177. internal Array(Type eType, byte TypeId) : base(TypeId) {
  178. elemType = eType;
  179. tabIx = MDTable.TypeSpec;
  180. }
  181. }
  182. /**************************************************************************/
  183. /// <summary>
  184. /// Single dimensional array with zero lower bound
  185. /// </summary>
  186. public class ZeroBasedArray : Array {
  187. /// <summary>
  188. /// Create a new array - elementType[]
  189. /// </summary>
  190. /// <param name="elementType">the type of the array elements</param>
  191. public ZeroBasedArray(Type elementType) : base (elementType,0x1D) { }
  192. internal sealed override void TypeSig(MemoryStream str) {
  193. str.WriteByte(typeIndex);
  194. elemType.TypeSig(str);
  195. }
  196. }
  197. /**************************************************************************/
  198. /// <summary>
  199. /// Multi dimensional array with explicit bounds
  200. /// </summary>
  201. public class BoundArray : Array {
  202. int[] lowerBounds;
  203. int[] sizes;
  204. uint numDims;
  205. /// <summary>
  206. /// Create a new multi dimensional array type
  207. /// eg. elemType[1..5,3..10,5,,] would be
  208. /// new BoundArray(elemType,5,[1,3,0],[5,10,4])
  209. /// </summary>
  210. /// <param name="elementType">the type of the elements</param>
  211. /// <param name="dimensions">the number of dimensions</param>
  212. /// <param name="loBounds">lower bounds of dimensions</param>
  213. /// <param name="upBounds">upper bounds of dimensions</param>
  214. public BoundArray(Type elementType, uint dimensions, int[] loBounds,
  215. int[] upBounds) : base (elementType,0x14) {
  216. numDims = dimensions;
  217. lowerBounds = loBounds;
  218. sizes = new int[loBounds.Length];
  219. for (int i=0; i < loBounds.Length; i++) {
  220. sizes[i] = upBounds[i] - loBounds[i] + 1;
  221. }
  222. }
  223. /// <summary>
  224. /// Create a new multi dimensional array type
  225. /// eg. elemType[5,10,20] would be new BoundArray(elemType,3,[5,10,20])
  226. /// </summary>
  227. /// <param name="elementType">the type of the elements</param>
  228. /// <param name="dimensions">the number of dimensions</param>
  229. /// <param name="size">the sizes of the dimensions</param>
  230. public BoundArray(Type elementType, uint dimensions, int[] size)
  231. : base (elementType,0x14) {
  232. numDims = dimensions;
  233. sizes = size;
  234. }
  235. /// <summary>
  236. /// Create a new multi dimensional array type
  237. /// eg. elemType[,,] would be new BoundArray(elemType,3)
  238. /// </summary>
  239. /// <param name="elementType">the type of the elements</param>
  240. /// <param name="dimensions">the number of dimensions</param>
  241. public BoundArray(Type elementType, uint dimensions)
  242. : base (elementType,0x14) {
  243. numDims = dimensions;
  244. }
  245. internal sealed override void TypeSig(MemoryStream str) {
  246. str.WriteByte(typeIndex);
  247. elemType.TypeSig(str);
  248. MetaData.CompressNum(numDims,str);
  249. if ((sizes != null) && (sizes.Length > 0)) {
  250. MetaData.CompressNum((uint)sizes.Length,str);
  251. for (int i=0; i < sizes.Length; i++) {
  252. MetaData.CompressNum((uint)sizes[i],str);
  253. }
  254. } else str.WriteByte(0);
  255. if ((lowerBounds != null) && (lowerBounds.Length > 0)) {
  256. MetaData.CompressNum((uint)lowerBounds.Length,str);
  257. for (int i=0; i < lowerBounds.Length; i++) {
  258. MetaData.CompressNum((uint)lowerBounds[i],str);
  259. }
  260. } else str.WriteByte(0);
  261. }
  262. }
  263. /**************************************************************************/
  264. /// <summary>
  265. /// Descriptor for THIS assembly (.assembly)
  266. /// </summary>
  267. public class Assembly : ResolutionScope
  268. {
  269. ushort majorVer, minorVer, buildNo, revisionNo;
  270. uint flags;
  271. uint hashAlgId;
  272. uint keyIx = 0, cultIx = 0;
  273. bool hasPublicKey = false;
  274. internal Assembly(string name, MetaData md) : base(name,md) {
  275. tabIx = MDTable.Assembly;
  276. }
  277. /// <summary>
  278. /// Add details about THIS assembly
  279. /// </summary>
  280. /// <param name="majVer">Major Version</param>
  281. /// <param name="minVer">Minor Version</param>
  282. /// <param name="bldNo">Build Number</param>
  283. /// <param name="revNo">Revision Number</param>
  284. /// <param name="key">Hash Key</param>
  285. /// <param name="hash">Hash Algorithm</param>
  286. /// <param name="cult">Culture</param>
  287. public void AddAssemblyInfo(int majVer, int minVer, int bldNo, int revNo,
  288. byte[] key, uint hash, string cult) {
  289. majorVer = (ushort)majVer;
  290. minorVer = (ushort)minVer;
  291. buildNo = (ushort)bldNo;
  292. revisionNo = (ushort)revNo;
  293. hashAlgId = hash;
  294. hasPublicKey = (key != null);
  295. keyIx = metaData.AddToBlobHeap(key);
  296. cultIx = metaData.AddToStringsHeap(cult);
  297. }
  298. /// <summary>
  299. /// Add an attribute to THIS assembly
  300. /// </summary>
  301. /// <param name="aa">assembly attribute</param>
  302. public void AddAssemblyAttr(AssemAttr aa) {
  303. flags |= (uint)aa;
  304. }
  305. internal sealed override uint Size(MetaData md) {
  306. return 16 + md.BlobIndexSize() + 2 * md.StringsIndexSize();
  307. }
  308. internal sealed override void Write(FileImage output) {
  309. // Console.WriteLine("Writing assembly element with nameIx of " + nameIx + " at file offset " + output.Seek(0,SeekOrigin.Current));
  310. output.Write((uint)hashAlgId);
  311. output.Write(majorVer);
  312. output.Write(minorVer);
  313. output.Write(buildNo);
  314. output.Write(revisionNo);
  315. output.Write(flags);
  316. output.BlobIndex(keyIx);
  317. output.StringsIndex(nameIx);
  318. output.StringsIndex(cultIx);
  319. }
  320. internal sealed override uint GetCodedIx(CIx code) {
  321. switch (code) {
  322. case (CIx.HasCustomAttr) : return 14;
  323. case (CIx.HasDeclSecurity) : return 2;
  324. }
  325. return 0;
  326. }
  327. internal bool HasPublicKey {
  328. get { return hasPublicKey; }
  329. }
  330. }
  331. /**************************************************************************/
  332. public interface IExternRef {
  333. ClassRef AddClass(string nsName, string name);
  334. ClassRef AddValueClass(string nsName, string name);
  335. }
  336. /// <summary>
  337. /// A reference to an external assembly (.assembly extern)
  338. /// </summary>
  339. public class AssemblyRef : ResolutionScope, IExternRef
  340. {
  341. private ushort major, minor, build, revision;
  342. uint flags, keyIx, hashIx, cultIx;
  343. bool hasVersion = false, isKeyToken = false;
  344. byte[] keyBytes;
  345. string culture;
  346. internal AssemblyRef(MetaData md, string name) : base(name,md) {
  347. tabIx = MDTable.AssemblyRef;
  348. }
  349. /// <summary>
  350. /// Add version information about this external assembly
  351. /// </summary>
  352. /// <param name="majVer">Major Version</param>
  353. /// <param name="minVer">Minor Version</param>
  354. /// <param name="bldNo">Build Number</param>
  355. /// <param name="revNo">Revision Number</param>
  356. public void AddVersionInfo(int majVer, int minVer, int bldNo, int revNo) {
  357. major = (ushort)majVer;
  358. minor = (ushort)minVer;
  359. build = (ushort)bldNo;
  360. revision = (ushort)revNo;
  361. hasVersion = true;
  362. }
  363. /// <summary>
  364. /// Add the hash value for this external assembly
  365. /// </summary>
  366. /// <param name="hash">bytes of the hash value</param>
  367. public void AddHash(byte[] hash) {
  368. hashIx = metaData.AddToBlobHeap(hash);
  369. }
  370. /// <summary>
  371. /// Set the culture for this external assembly
  372. /// </summary>
  373. /// <param name="cult">the culture string</param>
  374. public void AddCulture(string cult) {
  375. cultIx = metaData.AddToStringsHeap(cult);
  376. culture = cult;
  377. }
  378. /// <summary>
  379. /// Add the full public key for this external assembly
  380. /// </summary>
  381. /// <param name="key">bytes of the public key</param>
  382. public void AddKey(byte[] key) {
  383. flags |= 0x0001; // full public key
  384. keyBytes = key;
  385. keyIx = metaData.AddToBlobHeap(key);
  386. }
  387. /// <summary>
  388. /// Add the public key token (low 8 bytes of the public key)
  389. /// </summary>
  390. /// <param name="key">low 8 bytes of public key</param>
  391. public void AddKeyToken(byte[] key) {
  392. keyIx = metaData.AddToBlobHeap(key);
  393. keyBytes = key;
  394. isKeyToken = true;
  395. }
  396. /// <summary>
  397. /// Add a class to this external assembly
  398. /// </summary>
  399. /// <param name="nsName">name space name</param>
  400. /// <param name="name">class name</param>
  401. /// <returns></returns>
  402. public virtual ClassRef AddClass(string nsName, string name) {
  403. ClassRef aClass = new ClassRef(nsName,name,metaData);
  404. metaData.AddToTable(MDTable.TypeRef,aClass);
  405. aClass.SetParent(this);
  406. return aClass;
  407. }
  408. /// <summary>
  409. /// Add a value class to this external assembly
  410. /// </summary>
  411. /// <param name="nsName">name space name</param>
  412. /// <param name="name">class name</param>
  413. /// <returns></returns>
  414. public virtual ClassRef AddValueClass(string nsName, string name) {
  415. ClassRef aClass = new ClassRef(nsName,name,metaData);
  416. metaData.AddToTable(MDTable.TypeRef,aClass);
  417. aClass.SetParent(this);
  418. aClass.MakeValueClass();
  419. return aClass;
  420. }
  421. internal string TypeName() {
  422. string result = name;
  423. if (hasVersion)
  424. result = result + ", Version=" + major + "." + minor + "." +
  425. build + "." + revision;
  426. if (keyBytes != null) {
  427. string tokenStr = "=";
  428. if (isKeyToken) tokenStr = "Token=";
  429. result = result + ", PublicKey" + tokenStr;
  430. for (int i=0; i < keyBytes.Length; i++) {
  431. result = result + Hex.Byte(keyBytes[i]);
  432. }
  433. }
  434. if (culture != null)
  435. result = result + ", Culture=" + culture;
  436. return result;
  437. }
  438. internal sealed override uint Size(MetaData md) {
  439. return 12 + 2 * md.StringsIndexSize() + 2 * md.BlobIndexSize();
  440. }
  441. internal sealed override void Write(FileImage output) {
  442. output.Write(major);
  443. output.Write(minor);
  444. output.Write(build);
  445. output.Write(revision);
  446. output.Write(flags);
  447. output.BlobIndex(keyIx);
  448. output.StringsIndex(nameIx);
  449. output.StringsIndex(cultIx);
  450. output.BlobIndex(hashIx);
  451. }
  452. internal sealed override uint GetCodedIx(CIx code) {
  453. switch (code) {
  454. case (CIx.ResolutionScope) : return 2;
  455. case (CIx.HasCustomAttr) : return 15;
  456. case (CIx.Implementation) : return 1;
  457. }
  458. return 0;
  459. }
  460. }
  461. /**************************************************************************/
  462. /// <summary>
  463. /// flags for the assembly (.corflags)
  464. /// </summary>
  465. public enum CorFlags {CF_IL_ONLY = 1, CF_32_BITREQUIRED = 2,
  466. CF_STRONGNAMESIGNED = 8, CF_TRACKDEBUGDATA = 0x10000 }
  467. /// <summary>
  468. /// subsystem for the assembly (.subsystem)
  469. /// </summary>
  470. public enum SubSystem { Native = 1, Windows_GUI = 2,
  471. Windows_CUI = 3, OS2_CUI = 5, POSIX_CUI = 7, Native_Windows = 8,
  472. Windows_CE_GUI = 9}
  473. /// <summary>
  474. /// Hash algorithms for the assembly
  475. /// </summary>
  476. public enum HashAlgorithm { None, SHA1 }
  477. /// <summary>
  478. /// Attributes for this assembly
  479. /// </summary>
  480. public enum AssemAttr { EnableJITCompileTracking = 0x8000,
  481. DisableJITCompileOptimizer = 0x4000}
  482. /// <summary>
  483. /// Method call conventions
  484. /// </summary>
  485. public enum CallConv { Default, Cdecl, Stdcall, Thiscall,
  486. Fastcall, Vararg, Instance = 0x20, Generic = 0x10, InstanceExplicit = 0x60 }
  487. /// <summary>
  488. /// Type custom modifier
  489. /// </summary>
  490. public enum CustomModifier { modreq = 0x1F, modopt };
  491. /// <summary>
  492. /// Attibutes for a class
  493. /// </summary>
  494. public enum TypeAttr {Private, Public, NestedPublic, NestedPrivate,
  495. NestedFamily, NestedAssembly, NestedFamAndAssem, NestedFamOrAssem,
  496. SequentialLayout, ExplicitLayout = 0x10, Interface = 0x20,
  497. Abstract = 0x80, PublicAbstract = 0x81, Sealed = 0x100,
  498. PublicSealed = 0x101, SpecialName = 0x400, RTSpecialName = 0x800,
  499. Import = 0x1000, Serializable = 0x2000, UnicodeClass = 0x10000,
  500. AutoClass = 0x20000, BeforeFieldInit = 0x100000 }
  501. /// <summary>
  502. /// Attributes for a field
  503. /// </summary>
  504. public enum FieldAttr {Default, Private, FamAndAssem, Assembly,
  505. Family, FamOrAssem, Public, Static = 0x10, PublicStatic = 0x16,
  506. Initonly = 0x20, Literal = 0x40, Notserialized = 0x80,
  507. SpecialName = 0x200, RTSpecialName = 0x400 }
  508. /// <summary>
  509. /// Attributes for a method
  510. /// </summary>
  511. public enum MethAttr { Default, Private, FamAndAssem, Assembly,
  512. Family, FamOrAssem, Public, Static = 0x0010, PublicStatic = 0x16,
  513. Final = 0x0020, PublicStaticFinal = 0x36, Virtual = 0x0040,
  514. PrivateVirtual, PublicVirtual = 0x0046, HideBySig = 0x0080,
  515. NewSlot = 0x0100, Abstract = 0x0400, SpecialName = 0x0800,
  516. RTSpecialName = 0x1000, SpecialRTSpecialName = 0x1800,
  517. RequireSecObject = 0x8000}
  518. /// <summary>
  519. /// Attributes for .pinvokeimpl method declarations
  520. /// </summary>
  521. public enum PInvokeAttr { nomangle = 1, ansi = 2, unicode = 4, autochar = 6,
  522. lasterr = 0x0040, winapi = 0x0100, cdecl = 0x0200,
  523. stdcall = 0x0300, thiscall = 0x0400, fastcall = 0x0500 }
  524. /// <summary>
  525. /// Implementation attributes for a method
  526. /// </summary>
  527. public enum ImplAttr { IL, Native, Runtime = 0x03, Unmanaged = 0x04,
  528. ForwardRef = 0x10, PreserveSig = 0x0080, InternalCall = 0x1000,
  529. Synchronised = 0x0020, Synchronized = 0x0020, NoInLining = 0x0008, Optil = 0x0002}
  530. /// <summary>
  531. /// Modes for a parameter
  532. /// </summary>
  533. public enum ParamAttr { Default, In, Out, Opt = 4 }
  534. /// <summary>
  535. /// CIL instructions
  536. /// </summary>
  537. public enum Op { nop, breakOp, ldarg_0, ldarg_1, ldarg_2, ldarg_3,
  538. ldloc_0, ldloc_1, ldloc_2, ldloc_3, stloc_0, stloc_1, stloc_2, stloc_3,
  539. ldnull = 0x14, ldc_i4_m1, ldc_i4_0, ldc_i4_1, ldc_i4_2, ldc_i4_3,
  540. ldc_i4_4, ldc_i4_5, ldc_i4_6, ldc_i4_7, ldc_i4_8, dup = 0x25, pop,
  541. ret = 0x2A, ldind_i1 = 0x46, ldind_u1, ldind_i2, ldind_u2, ldind_i4,
  542. ldind_u4, ldind_i8, ldind_i, ldind_r4, ldind_r8, ldind_ref, stind_ref,
  543. stind_i1, stind_i2, stind_i4, stind_i8, stind_r4, stind_r8, add, sub, mul,
  544. div, div_un, rem, rem_un, and, or, xor, shl, shr, shr_un, neg, not,
  545. conv_i1, conv_i2, conv_i4, conv_i8, conv_r4, conv_r8, conv_u4, conv_u8,
  546. conv_r_un = 0x76, throwOp = 0x7A, conv_ovf_i1_un = 0x82, conv_ovf_i2_un,
  547. conv_ovf_i4_un, conv_ovf_i8_un, conf_ovf_u1_un, conv_ovf_u2_un,
  548. conv_ovf_u4_un, conv_ovf_u8_un, conv_ovf_i_un, conv_ovf_u_un,
  549. ldlen = 0x8E, ldelem_i1 = 0x90, ldelem_u1, ldelem_i2, ldelem_u2,
  550. ldelem_i4, ldelem_u4, ldelem_i8, ldelem_i, ldelem_r4, ldelem_r8,
  551. ldelem_ref, stelem_i, stelem_i1, stelem_i2, stelem_i4, stelem_i8, stelem_r4 = 0xA0, stelem_r8,
  552. stelem_ref, conv_ovf_i1 = 0xb3, conv_ovf_u1, conv_ovf_i2, conv_ovf_u2,
  553. conv_ovf_i4, conv_ovf_u4, conv_ovf_i8, conv_ovf_u8, ckfinite = 0xC3,
  554. conv_u2 = 0xD1, conv_u1, conv_i, conv_ovf_i, conv_ovf_u, add_ovf,
  555. add_ovf_un, mul_ovf, mul_ovf_un, sub_ovf, sub_ovf_un, endfinally,
  556. stind_i = 0xDF, conv_u, arglist = 0xFE00, ceq, cgt, cgt_un, clt, clt_un,
  557. localloc = 0xFE0F, endfilter = 0xFE11, volatile_ = 0xFE13, tail_,
  558. cpblk = 0xFE17, initblk, rethrow = 0xFE1A, refanytype = 0xFE1D}
  559. /// <summary>
  560. /// CIL instructions requiring an integer parameter
  561. /// </summary>
  562. public enum IntOp {ldarg_s = 0x0E, ldarga_s, starg_s, ldloc_s, ldloca_s,
  563. stloc_s, ldc_i4_s = 0x1F, ldc_i4, ldarg = 0xFE09,
  564. ldarga, starg, ldloc, ldloca, stloc, unaligned = 0xFE12 }
  565. /// <summary>
  566. /// CIL instructions requiring a field parameter
  567. /// </summary>
  568. public enum FieldOp {ldfld = 0x7B, ldflda, stfld, ldsfld, ldsflda,
  569. stsfld, ldtoken = 0xD0 }
  570. /// <summary>
  571. /// CIL instructions requiring a method parameter
  572. /// </summary>
  573. public enum MethodOp {jmp = 0x27, call, callvirt = 0x6F, newobj = 0x73,
  574. ldtoken = 0xD0, ldftn = 0xFE06, ldvirtfn }
  575. /// <summary>
  576. /// CIL instructions requiring a type parameter
  577. /// </summary>
  578. public enum TypeOp {cpobj = 0x70, ldobj, castclass = 0x74, isinst,
  579. unbox = 0x79, stobj = 0x81, box = 0x8C, newarr,
  580. ldelema = 0x8F, refanyval = 0xC2, mkrefany = 0xC6,
  581. ldtoken = 0xD0, initobj = 0xFE15, sizeOf = 0xFE1C,
  582. ldelem = 0xA3, stelem = 0xA4, unbox_any }
  583. /// <summary>
  584. /// CIL branch instructions
  585. /// </summary>
  586. public enum BranchOp {
  587. // short branches
  588. br_s = 0x2B, brfalse_s, brtrue_s, beq_s, bge_s, bgt_s,
  589. ble_s, blt_s, bne_un_s, bge_un_s, bgt_un_s, ble_un_s, blt_un_s,
  590. // long branches
  591. br = 0x38, brfalse, brtrue, beq, bge, bgt, ble, blt,
  592. bne_un, bge_un, bgt_un, ble_un, blt_un,
  593. leave = 0xDD, leave_s }
  594. /// <summary>
  595. /// Index for all the tables in the meta data
  596. /// </summary>
  597. public enum MDTable { Module, TypeRef, TypeDef, Field = 0x04, Method = 0x06,
  598. Param = 0x08, InterfaceImpl, MemberRef, Constant, CustomAttribute,
  599. FieldMarshal, DeclSecurity, ClassLayout, FieldLayout, StandAloneSig,
  600. EventMap, Event = 0x14, PropertyMap, Property = 0x17, MethodSemantics,
  601. MethodImpl, ModuleRef, TypeSpec, ImplMap, FieldRVA, Assembly = 0x20,
  602. AssemblyProcessor, AssemblyOS, AssemblyRef, AssemblyRefProcessor,
  603. AssemblyRefOS, File, ExportedType, ManifestResource, NestedClass,
  604. GenericParam, MethodSpec, GenericParamConstraint }
  605. public enum SafeArrayType { int16 = 2, int32, float32, float64,
  606. currency, date, bstr, dispatch, error, boolean, variant, unknown,
  607. Decimal, int8 = 16, uint8, uint16, uint32, Int = 22, UInt }
  608. internal enum CIx { TypeDefOrRef, HasConst, HasCustomAttr, HasFieldMarshal,
  609. HasDeclSecurity, MemberRefParent, HasSemantics, MethodDefOrRef,
  610. MemberForwarded, Implementation, CustomAttributeType, ResolutionScope,
  611. TypeOrMethodDef, MaxCIx }
  612. internal enum MapType { eventMap, propertyMap, nestedClass }
  613. /**************************************************************************/
  614. /// <summary>
  615. /// The assembly for mscorlib.
  616. /// </summary>
  617. public sealed class MSCorLib : AssemblyRef
  618. {
  619. private static readonly int valueTypeIx = 18;
  620. private readonly string systemName = "System";
  621. private ClassRef[] systemClasses = new ClassRef[valueTypeIx+2];
  622. private PrimitiveType[] systemTypes = new PrimitiveType[valueTypeIx];
  623. private TypeSpec[] specialTypeSpecs = new TypeSpec[valueTypeIx];
  624. private static int[] specialNames = {
  625. PrimitiveType.Void.GetName().GetHashCode(),
  626. PrimitiveType.Boolean.GetName().GetHashCode(),
  627. PrimitiveType.Char.GetName().GetHashCode(),
  628. PrimitiveType.Int8.GetName().GetHashCode(),
  629. PrimitiveType.UInt8.GetName().GetHashCode(),
  630. PrimitiveType.Int16.GetName().GetHashCode(),
  631. PrimitiveType.UInt16.GetName().GetHashCode(),
  632. PrimitiveType.Int32.GetName().GetHashCode(),
  633. PrimitiveType.UInt32.GetName().GetHashCode(),
  634. PrimitiveType.Int64.GetName().GetHashCode(),
  635. PrimitiveType.UInt64.GetName().GetHashCode(),
  636. PrimitiveType.Float32.GetName().GetHashCode(),
  637. PrimitiveType.Float64.GetName().GetHashCode(),
  638. PrimitiveType.String.GetName().GetHashCode(),
  639. PrimitiveType.TypedRef.GetName().GetHashCode(),
  640. PrimitiveType.IntPtr.GetName().GetHashCode(),
  641. PrimitiveType.UIntPtr.GetName().GetHashCode(),
  642. PrimitiveType.Object.GetName().GetHashCode(),
  643. "ValueType".GetHashCode(),
  644. "Enum".GetHashCode()
  645. };
  646. internal MSCorLib(MetaData md) : base(md,"mscorlib") {
  647. md.AddToTable(MDTable.AssemblyRef,this);
  648. systemTypes[PrimitiveType.Void.GetSystemTypeIx()] = PrimitiveType.Void;
  649. systemTypes[PrimitiveType.Boolean.GetSystemTypeIx()] = PrimitiveType.Boolean;
  650. systemTypes[PrimitiveType.Char.GetSystemTypeIx()] = PrimitiveType.Char;
  651. systemTypes[PrimitiveType.Int8.GetSystemTypeIx()] = PrimitiveType.Int8;
  652. systemTypes[PrimitiveType.UInt8.GetSystemTypeIx()] = PrimitiveType.UInt8;
  653. systemTypes[PrimitiveType.Int16.GetSystemTypeIx()] = PrimitiveType.Int16;
  654. systemTypes[PrimitiveType.UInt16.GetSystemTypeIx()] = PrimitiveType.UInt16;
  655. systemTypes[PrimitiveType.Int32.GetSystemTypeIx()] = PrimitiveType.Int32;
  656. systemTypes[PrimitiveType.UInt32.GetSystemTypeIx()] = PrimitiveType.UInt32;
  657. systemTypes[PrimitiveType.Int64.GetSystemTypeIx()] = PrimitiveType.Int64;
  658. systemTypes[PrimitiveType.UInt64.GetSystemTypeIx()] = PrimitiveType.UInt64;
  659. systemTypes[PrimitiveType.Float32.GetSystemTypeIx()] = PrimitiveType.Float32;
  660. systemTypes[PrimitiveType.Float64.GetSystemTypeIx()] = PrimitiveType.Float64;
  661. systemTypes[PrimitiveType.IntPtr.GetSystemTypeIx()] = PrimitiveType.IntPtr;
  662. systemTypes[PrimitiveType.UIntPtr.GetSystemTypeIx()] = PrimitiveType.UIntPtr;
  663. systemTypes[PrimitiveType.String.GetSystemTypeIx()] = PrimitiveType.String;
  664. systemTypes[PrimitiveType.Object.GetSystemTypeIx()] = PrimitiveType.Object;
  665. systemTypes[PrimitiveType.TypedRef.GetSystemTypeIx()] = PrimitiveType.TypedRef;
  666. }
  667. /// <summary>
  668. /// Add a class to the mscorlib assembly
  669. /// </summary>
  670. /// <param name="nsName">name space name</param>
  671. /// <param name="name">class name</param>
  672. /// <returns></returns>
  673. public override ClassRef AddClass(string nsName, string name) {
  674. ClassRef aClass = GetSpecialClass(nsName,name);
  675. if (aClass == null) {
  676. aClass = new ClassRef(nsName,name,metaData);
  677. metaData.AddToTable(MDTable.TypeRef,aClass);
  678. aClass.SetParent(this);
  679. }
  680. return aClass;
  681. }
  682. private ClassRef GetSpecialClass(string nsName,string name) {
  683. if (nsName.CompareTo(systemName) != 0) return null;
  684. int hash = name.GetHashCode();
  685. for (int i=0; i < specialNames.Length; i++) {
  686. if (hash == specialNames[i]) {
  687. if (systemClasses[i] == null) {
  688. if (i < valueTypeIx) {
  689. systemClasses[i] = new SystemClass(systemTypes[i],this,metaData);
  690. if ((systemTypes[i] != PrimitiveType.Object) &&
  691. (systemTypes[i] != PrimitiveType.String)) {
  692. systemClasses[i].MakeValueClass();
  693. }
  694. } else {
  695. systemClasses[i] = new ClassRef(nsName,name,metaData);
  696. systemClasses[i].SetParent(this);
  697. systemClasses[i].MakeValueClass();
  698. }
  699. metaData.AddToTable(MDTable.TypeRef,systemClasses[i]);
  700. }
  701. return systemClasses[i];
  702. }
  703. }
  704. return null;
  705. }
  706. internal ClassRef GetSpecialSystemClass(PrimitiveType pType) {
  707. int ix = pType.GetSystemTypeIx();
  708. if (systemClasses[ix] == null) {
  709. systemClasses[ix] = new SystemClass(pType,this,metaData);
  710. metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
  711. }
  712. return systemClasses[ix];
  713. }
  714. private ClassRef GetValueClass(string name, int hash) {
  715. int ix = valueTypeIx;
  716. if (hash != specialNames[valueTypeIx]) ix++;
  717. if (systemClasses[ix] == null) {
  718. systemClasses[ix] = new ClassRef(systemName,name,metaData);
  719. systemClasses[ix].SetParent(this);
  720. systemClasses[ix].MakeValueClass();
  721. metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
  722. }
  723. return systemClasses[ix];
  724. }
  725. internal ClassRef ValueType() {
  726. if (systemClasses[valueTypeIx] == null) {
  727. ClassRef valType = new ClassRef("System","ValueType",metaData);
  728. valType.SetParent(this);
  729. valType.MakeValueClass();
  730. metaData.AddToTable(MDTable.TypeRef,valType);
  731. systemClasses[valueTypeIx] = valType;
  732. }
  733. return systemClasses[valueTypeIx];
  734. }
  735. /// <summary>
  736. /// Add a value class to this external assembly
  737. /// </summary>
  738. /// <param name="nsName">name space name</param>
  739. /// <param name="name">class name</param>
  740. /// <returns></returns>
  741. public override ClassRef AddValueClass(string nsName, string name) {
  742. if (nsName.CompareTo(systemName) == 0) {
  743. int hash = name.GetHashCode();
  744. if ((hash == specialNames[valueTypeIx]) ||
  745. (hash == specialNames[valueTypeIx+1])) {
  746. return GetValueClass(name,hash);
  747. }
  748. }
  749. ClassRef aClass = new ClassRef(nsName,name,metaData);
  750. metaData.AddToTable(MDTable.TypeRef,aClass);
  751. aClass.SetParent(this);
  752. aClass.MakeValueClass();
  753. return aClass;
  754. }
  755. }
  756. /**************************************************************************/
  757. /// <summary>
  758. /// Signature for calli instruction
  759. /// </summary>
  760. public class CalliSig : Signature
  761. {
  762. private static readonly byte Sentinel = 0x41;
  763. CallConv callConv;
  764. Type returnType;
  765. Type[] parameters, optParams;
  766. uint numPars = 0, numOptPars = 0;
  767. /// <summary>
  768. /// Create a signature for a calli instruction
  769. /// </summary>
  770. /// <param name="cconv">calling conventions</param>
  771. /// <param name="retType">return type</param>
  772. /// <param name="pars">parameter types</param>
  773. public CalliSig(CallConv cconv, Type retType, Type[] pars) {
  774. tabIx = MDTable.StandAloneSig;
  775. callConv = cconv;
  776. returnType = retType;
  777. parameters = pars;
  778. if (pars != null) numPars = (uint)pars.Length;
  779. }
  780. /// <summary>
  781. /// Add the optional parameters to a vararg method
  782. /// This method sets the vararg calling convention
  783. /// </summary>
  784. /// <param name="optPars">the optional pars for the vararg call</param>
  785. public void AddVarArgs(Type[] optPars) {
  786. optParams = optPars;
  787. if (optPars != null) numOptPars = (uint)optPars.Length;
  788. callConv |= CallConv.Vararg;
  789. }
  790. /// <summary>
  791. /// Add extra calling conventions to this callsite signature
  792. /// </summary>
  793. /// <param name="cconv"></param>
  794. public void AddCallingConv(CallConv cconv) {
  795. callConv |= cconv;
  796. }
  797. internal sealed override void BuildTables(MetaData md) {
  798. if (done) return;
  799. MemoryStream sig = new MemoryStream();
  800. sig.WriteByte((byte)callConv);
  801. MetaData.CompressNum(numPars+numOptPars,sig);
  802. returnType.TypeSig(sig);
  803. for (int i=0; i < numPars; i++) {
  804. parameters[i].TypeSig(sig);
  805. }
  806. sigIx = md.AddToBlobHeap(sig.ToArray());
  807. if (numOptPars > 0) {
  808. sig.WriteByte(Sentinel);
  809. for (int i=0; i < numOptPars; i++) {
  810. optParams[i].TypeSig(sig);
  811. }
  812. }
  813. done = true;
  814. }
  815. }
  816. /**************************************************************************/
  817. /// <summary>
  818. /// The IL instructions for a method
  819. /// </summary>
  820. public class CILInstructions
  821. {
  822. private static readonly uint ExHeaderSize = 4;
  823. private static readonly uint FatExClauseSize = 24;
  824. private static readonly uint SmlExClauseSize = 12;
  825. private static readonly sbyte maxByteVal = 127;
  826. private static readonly sbyte minByteVal = -128;
  827. private static readonly byte maxUByteVal = 255;
  828. private static readonly int smallSize = 64;
  829. private static readonly ushort TinyFormat = 0x2;
  830. private static readonly ushort FatFormat = 0x3003;
  831. private static readonly ushort MoreSects = 0x8;
  832. private static readonly ushort InitLocals = 0x10;
  833. private static readonly uint FatSize = 12;
  834. private static readonly uint FatWords = FatSize/4;
  835. private static readonly byte FatExceptTable = 0x41;
  836. private static readonly byte SmlExceptTable = 0x01;
  837. private MetaData metaData;
  838. private ArrayList exceptions, blockStack;
  839. //private bool codeChecked = false;
  840. private static readonly int INITSIZE = 5;
  841. private CILInstruction[] buffer = new CILInstruction[INITSIZE];
  842. private int tide = 0;
  843. private uint offset = 0;
  844. private ushort headerFlags = 0;
  845. private short maxStack;
  846. private uint paddingNeeded = 0;
  847. private byte exceptHeader = 0;
  848. uint localSigIx = 0;
  849. uint codeSize = 0, exceptSize = 0;
  850. bool tinyFormat, fatExceptionFormat = false;
  851. public uint Offset {
  852. get { return offset; }
  853. }
  854. internal CILInstructions(MetaData md) {
  855. metaData = md;
  856. }
  857. private void AddToBuffer(CILInstruction inst) {
  858. if (tide >= buffer.Length) {
  859. CILInstruction[] tmp = buffer;
  860. buffer = new CILInstruction[tmp.Length * 2];
  861. for (int i=0; i < tide; i++) {
  862. buffer[i] = tmp[i];
  863. }
  864. }
  865. //Console.WriteLine("Adding instruction at offset " + offset + " with size " + inst.size);
  866. inst.offset = offset;
  867. offset += inst.size;
  868. buffer[tide++] = inst;
  869. }
  870. /// <summary>
  871. /// Add a simple IL instruction
  872. /// </summary>
  873. /// <param name="inst">the IL instruction</param>
  874. public void Inst(Op inst) {
  875. AddToBuffer(new Instr((int)inst));
  876. }
  877. /// <summary>
  878. /// Add an IL instruction with an integer parameter
  879. /// </summary>
  880. /// <param name="inst">the IL instruction</param>
  881. /// <param name="val">the integer parameter value</param>
  882. public void IntInst(IntOp inst, int val) {
  883. int instr = (int)inst;
  884. if ((inst == IntOp.ldc_i4_s) || (inst == IntOp.ldc_i4))
  885. AddToBuffer(new IntInstr(instr,val,(inst == IntOp.ldc_i4_s)));
  886. else
  887. AddToBuffer(new UIntInstr(instr,val,((inst < IntOp.ldc_i4_s) ||
  888. (inst == IntOp.unaligned))));
  889. }
  890. /// <summary>
  891. /// Add the load long instruction
  892. /// </summary>
  893. /// <param name="cVal">the long value</param>
  894. public void ldc_i8(long cVal) {
  895. AddToBuffer(new LongInstr(0x21,cVal));
  896. }
  897. /// <summary>
  898. /// Add the load float32 instruction
  899. /// </summary>
  900. /// <param name="cVal">the float value</param>
  901. public void ldc_r4(float cVal) {
  902. AddToBuffer(new FloatInstr(0x22,cVal));
  903. }
  904. /// <summary>
  905. /// Add the load float64 instruction
  906. /// </summary>
  907. /// <param name="cVal">the float value</param>
  908. public void ldc_r8(double cVal) {
  909. AddToBuffer(new DoubleInstr(0x23,cVal));
  910. }
  911. /// <summary>
  912. /// Add the load string instruction
  913. /// </summary>
  914. /// <param name="str">the string value</param>
  915. public void ldstr(string str) {
  916. AddToBuffer(new StringInstr(0x72,str));
  917. }
  918. /// <summary>
  919. /// Add the load string instruction
  920. /// </summary>
  921. public void ldstr (byte[] str) {
  922. AddToBuffer (new StringInstr (0x72, str));
  923. }
  924. /// <summary>
  925. /// Add the calli instruction
  926. /// </summary>
  927. /// <param name="sig">the signature for the calli</param>
  928. public void calli(CalliSig sig) {
  929. AddToBuffer(new SigInstr(0x29,sig));
  930. }
  931. /// <summary>
  932. /// Add a label to the CIL instructions
  933. /// </summary>
  934. /// <param name="lab">the label to be added</param>
  935. public void CodeLabel(CILLabel lab) {
  936. AddToBuffer(new LabelInstr(lab));
  937. }
  938. /// <summary>
  939. /// Add an instruction with a field parameter
  940. /// </summary>
  941. /// <param name="inst">the CIL instruction</param>
  942. /// <param name="f">the field parameter</param>
  943. public void FieldInst(FieldOp inst, Field f) {
  944. AddToBuffer(new FieldInstr((int)inst,f));
  945. }
  946. /// <summary>
  947. /// Add an instruction with a method parameter
  948. /// </summary>
  949. /// <param name="inst">the CIL instruction</param>
  950. /// <param name="m">the method parameter</param>
  951. public void MethInst(MethodOp inst, Method m) {
  952. AddToBuffer(new MethInstr((int)inst,m));
  953. }
  954. /// <summary>
  955. /// Add an instruction with a type parameter
  956. /// </summary>
  957. /// <param name="inst">the CIL instruction</param>
  958. /// <param name="t">the type argument for the CIL instruction</param>
  959. public void TypeInst(TypeOp inst, Type aType) {
  960. AddToBuffer(new TypeInstr((int)inst,aType,metaData));
  961. }
  962. /// <summary>
  963. /// Add a branch instruction
  964. /// </summary>
  965. /// <param name="inst">the branch instruction</param>
  966. /// <param name="lab">the label that is the target of the branch</param>
  967. public void Branch(BranchOp inst, CILLabel lab) {
  968. AddToBuffer(new BranchInstr((int)inst,lab));
  969. }
  970. /// <summary>
  971. /// Add a switch instruction
  972. /// </summary>
  973. /// <param name="labs">the target labels for the switch</param>
  974. public void Switch(CILLabel[] labs) {
  975. AddToBuffer(new SwitchInstr(0x45,labs));
  976. }
  977. /// <summary>
  978. /// Add a byte to the CIL instructions (.emitbyte)
  979. /// </summary>
  980. /// <param name="bVal"></param>
  981. public void emitbyte(byte bVal) {
  982. AddToBuffer(new CILByte(bVal));
  983. }
  984. /// <summary>
  985. /// Add an instruction which puts an integer on TOS. This method
  986. /// selects the correct instruction based on the value of the integer.
  987. /// </summary>
  988. /// <param name="i">the integer value</param>
  989. public void PushInt(int i) {
  990. if (i == -1) {
  991. AddToBuffer(new Instr((int)Op.ldc_i4_m1));
  992. } else if ((i >= 0) && (i <= 8)) {
  993. Op op = (Op)(Op.ldc_i4_0 + i);
  994. AddToBuffer(new Instr((int)op));
  995. } else if ((i >= minByteVal) && (i <= maxByteVal)) {
  996. AddToBuffer(new IntInstr((int)IntOp.ldc_i4_s,i,true));
  997. } else {
  998. AddToBuffer(new IntInstr((int)IntOp.ldc_i4,i,false));
  999. }
  1000. }
  1001. /// <summary>
  1002. /// Add the instruction to load a long on TOS
  1003. /// </summary>
  1004. /// <param name="l">the long value</param>
  1005. public void PushLong(long l) {
  1006. AddToBuffer(new LongInstr(0x21,l));
  1007. }
  1008. /// <summary>
  1009. /// Add an instruction to push the boolean value true on TOS
  1010. /// </summary>
  1011. public void PushTrue() {
  1012. AddToBuffer(new Instr((int)Op.ldc_i4_1));
  1013. }
  1014. /// <summary>
  1015. /// Add an instruction to push the boolean value false on TOS
  1016. /// </summary>
  1017. public void PushFalse() {
  1018. AddToBuffer(new Instr((int)Op.ldc_i4_0));
  1019. }
  1020. /// <summary>
  1021. /// Add the instruction to load an argument on TOS. This method
  1022. /// selects the correct instruction based on the value of argNo
  1023. /// </summary>
  1024. /// <param name="argNo">the number of the argument</param>
  1025. public void LoadArg(int argNo) {
  1026. if (argNo < 4) {
  1027. int op = (int)Op.ldarg_0 + argNo;
  1028. AddToBuffer(new Instr(op));
  1029. } else if (argNo <= maxUByteVal) {
  1030. AddToBuffer(new UIntInstr((int)IntOp.ldarg,argNo,true));
  1031. } else {
  1032. AddToBuffer(new UIntInstr(0x09,argNo,false));
  1033. }
  1034. }
  1035. /// <summary>
  1036. /// Add the instruction to load the address of an argument on TOS.
  1037. /// This method selects the correct instruction based on the value
  1038. /// of argNo.
  1039. /// </summary>
  1040. /// <param name="argNo">the number of the argument</param>
  1041. public void LoadArgAdr(int argNo) {
  1042. if (argNo <= maxUByteVal) {
  1043. AddToBuffer(new UIntInstr((int)IntOp.ldarga,argNo,true));
  1044. } else {
  1045. AddToBuffer(new UIntInstr(0x0A,argNo,false));
  1046. }
  1047. }
  1048. /// <summary>
  1049. /// Add the instruction to load a local on TOS. This method selects
  1050. /// the correct instruction based on the value of locNo.
  1051. /// </summary>
  1052. /// <param name="locNo">the number of the local to load</param>
  1053. public void LoadLocal(int locNo) {
  1054. if (locNo < 4) {
  1055. int op = (int)Op.ldloc_0 + locNo;
  1056. AddToBuffer(new Instr(op));
  1057. } else if (locNo <= maxUByteVal) {
  1058. AddToBuffer(new UIntInstr((int)IntOp.ldloc,locNo,true));
  1059. } else {
  1060. AddToBuffer(new UIntInstr(0x0C,locNo,false));
  1061. }
  1062. }
  1063. /// <summary>
  1064. /// Add the instruction to load the address of a local on TOS.
  1065. /// This method selects the correct instruction based on the
  1066. /// value of locNo.
  1067. /// </summary>
  1068. /// <param name="locNo">the number of the local</param>
  1069. public void LoadLocalAdr(int locNo) {
  1070. if (locNo <= maxUByteVal) {
  1071. AddToBuffer(new UIntInstr((int)IntOp.ldloca,locNo,true));
  1072. } else {
  1073. AddToBuffer(new UIntInstr(0x0D,locNo,false));
  1074. }
  1075. }
  1076. /// <summary>
  1077. /// Add the instruction to store to an argument. This method
  1078. /// selects the correct instruction based on the value of argNo.
  1079. /// </summary>
  1080. /// <param name="argNo">the argument to be stored to</param>
  1081. public void StoreArg(int argNo) {
  1082. if (argNo <= maxUByteVal) {
  1083. AddToBuffer(new UIntInstr((int)IntOp.starg,argNo,true));
  1084. } else {
  1085. AddToBuffer(new UIntInstr(0x0B,argNo,false));
  1086. }
  1087. }
  1088. /// <summary>
  1089. /// Add the instruction to store to a local. This method selects
  1090. /// the correct instruction based on the value of locNo.
  1091. /// </summary>
  1092. /// <param name="locNo">the local to be stored to</param>
  1093. public void StoreLocal(int locNo) {
  1094. if (locNo < 4) {
  1095. int op = (int)Op.stloc_0 + locNo;
  1096. AddToBuffer(new Instr(op));
  1097. } else if (locNo <= maxUByteVal) {
  1098. AddToBuffer(new UIntInstr((int)IntOp.stloc,locNo,true));
  1099. } else {
  1100. AddToBuffer(new UIntInstr(0x0E,locNo,false));
  1101. }
  1102. }
  1103. /// <summary>
  1104. /// Create a new CIL label. To place the label in the CIL instruction
  1105. /// stream use CodeLabel.
  1106. /// </summary>
  1107. /// <returns>a new CIL label</returns>
  1108. public CILLabel NewLabel() {
  1109. return new CILLabel();
  1110. }
  1111. public void AddTryBlock(TryBlock tryBlock) {
  1112. if (exceptions == null)
  1113. exceptions = new ArrayList();
  1114. else if (exceptions.Contains(tryBlock)) return;
  1115. exceptions.Add(tryBlock);
  1116. }
  1117. /// <summary>
  1118. /// Create a new label at this position in the code buffer
  1119. /// </summary>
  1120. /// <returns>the label at the current position</returns>
  1121. public CILLabel NewCodedLabel() {
  1122. CILLabel lab = new CILLabel();
  1123. AddToBuffer(new LabelInstr(lab));
  1124. return lab;
  1125. }
  1126. /// <summary>
  1127. /// Mark this position as the start of a new block
  1128. /// (try, catch, filter, finally or fault)
  1129. /// </summary>
  1130. public void StartBlock() {
  1131. if (blockStack == null) blockStack = new ArrayList();
  1132. blockStack.Insert(0,NewCodedLabel());
  1133. }
  1134. /// <summary>
  1135. /// Mark this position as the end of the last started block and
  1136. /// make it a try block. This try block is added to the current
  1137. /// instructions (ie do not need to call AddTryBlock)
  1138. /// </summary>
  1139. /// <returns>The try block just ended</returns>
  1140. public TryBlock EndTryBlock() {
  1141. TryBlock tBlock = new TryBlock((CILLabel)blockStack[0],NewCodedLabel());
  1142. blockStack.RemoveAt(0);
  1143. AddTryBlock(tBlock);
  1144. return tBlock;
  1145. }
  1146. /// <summary>
  1147. /// Mark this position as the end of the last started block and
  1148. /// make it a catch block. This catch block is associated with the
  1149. /// specified try block.
  1150. /// </summary>
  1151. /// <param name="exceptType">the exception type to be caught</param>
  1152. /// <param name="tryBlock">the try block associated with this catch block</param>
  1153. public void EndCatchBlock(Class exceptType, TryBlock tryBlock) {
  1154. Catch catchBlock = new Catch(exceptType,(CILLabel)blockStack[0],
  1155. NewCodedLabel());
  1156. tryBlock.AddHandler(catchBlock);
  1157. }
  1158. /// <summary>
  1159. /// Mark this position as the end of the last started block and
  1160. /// make it a filter block. This filter block is associated with the
  1161. /// specified try block.
  1162. /// </summary>
  1163. /// <param name="filterLab">the label where the filter code is</param>
  1164. /// <param name="tryBlock">the try block associated with this filter block</param>
  1165. public void EndFilterBlock(CILLabel filterLab, TryBlock tryBlock) {
  1166. Filter filBlock = new Filter(filterLab,(CILLabel)blockStack[0],NewCodedLabel());
  1167. tryBlock.AddHandler(filBlock);
  1168. }
  1169. /// <summary>
  1170. /// Mark this position as the end of the last started block and
  1171. /// make it a finally block. This finally block is associated with the
  1172. /// specified try block.
  1173. /// </summary>
  1174. /// <param name="tryBlock">the try block associated with this finally block</param>
  1175. public void EndFinallyBlock(TryBlock tryBlock) {
  1176. Finally finBlock= new Finally((CILLabel)blockStack[0],NewCodedLabel());
  1177. tryBlock.AddHandler(finBlock);
  1178. }
  1179. /// <summary>
  1180. /// Mark this position as the end of the last started block and
  1181. /// make it a fault block. This fault block is associated with the
  1182. /// specified try block.
  1183. /// </summary>
  1184. /// <param name="tryBlock">the try block associated with this fault block</param>
  1185. public void EndFaultBlock(TryBlock tryBlock) {
  1186. Fault fBlock= new Fault((CILLabel)blockStack[0],NewCodedLabel());
  1187. tryBlock.AddHandler(fBlock);
  1188. }
  1189. internal uint GetCodeSize() {
  1190. return codeSize + paddingNeeded + exceptSize;
  1191. }
  1192. internal void CheckCode(uint locSigIx, bool initLocals, int maxStack) {
  1193. if (tide == 0) return;
  1194. bool changed = true;
  1195. while (changed) {
  1196. changed = false;
  1197. for (int i=0; i < tide; i++) {
  1198. changed = buffer[i].Check(metaData) || changed;
  1199. }
  1200. if (changed) {
  1201. for (int i=1; i < tide; i++) {
  1202. buffer[i].offset = buffer[i-1].offset + buffer[i-1].size;
  1203. }
  1204. offset = buffer[tide-1].offset + buffer[tide-1].size;
  1205. }
  1206. }
  1207. codeSize = offset;
  1208. // Console.WriteLine("codeSize before header added = " + codeSize);
  1209. if ((offset < smallSize) && (maxStack <= 8) && (locSigIx == 0) && (exceptions == null)) {
  1210. // can use tiny header
  1211. //Console.WriteLine("Tiny Header");
  1212. tinyFormat = true;
  1213. headerFlags = (ushort)(TinyFormat | ((ushort)codeSize << 2));
  1214. codeSize++;
  1215. if ((codeSize % 4) != 0) { paddingNeeded = 4 - (codeSize % 4); }
  1216. } else {
  1217. //Console.WriteLine("Fat Header");
  1218. tinyFormat = false;
  1219. localSigIx = locSigIx;
  1220. this.maxStack = (short)maxStack;
  1221. headerFlags = FatFormat;
  1222. if (exceptions != null) {
  1223. // Console.WriteLine("Got exceptions");
  1224. headerFlags |= MoreSects;
  1225. uint numExceptClauses = 0;
  1226. for (int i=0; i < exceptions.Count; i++) {
  1227. TryBlock tryBlock = (TryBlock)exceptions[i];
  1228. tryBlock.SetSize();
  1229. numExceptClauses += (uint)tryBlock.NumHandlers();
  1230. if (tryBlock.isFat()) fatExceptionFormat = true;
  1231. }
  1232. uint data_size = ExHeaderSize + numExceptClauses *
  1233. (fatExceptionFormat ? FatExClauseSize : SmlExClauseSize);
  1234. if (data_size > 256)
  1235. fatExceptionFormat = true;
  1236. // Console.WriteLine("numexceptclauses = " + numExceptClauses);
  1237. if (fatExceptionFormat) {
  1238. // Console.WriteLine("Fat exception format");
  1239. exceptHeader = FatExceptTable;
  1240. exceptSize = ExHeaderSize + numExceptClauses * FatExClauseSize;
  1241. } else {
  1242. // Console.WriteLine("Tiny exception format");
  1243. exceptHeader = SmlExceptTable;
  1244. exceptSize = ExHeaderSize + numExceptClauses * SmlExClauseSize;
  1245. }
  1246. // Console.WriteLine("exceptSize = " + exceptSize);
  1247. }
  1248. if (initLocals) headerFlags |= InitLocals;
  1249. if ((offset % 4) != 0) { paddingNeeded = 4 - (offset % 4); }
  1250. codeSize += FatSize;
  1251. }
  1252. // Console.WriteLine("codeSize = " + codeSize + " headerFlags = " +
  1253. // Hex.Short(headerFlags));
  1254. }
  1255. internal void Write(FileImage output) {
  1256. // Console.WriteLine("Writing header flags = " + Hex.Short(headerFlags));
  1257. if (tinyFormat) {
  1258. // Console.WriteLine("Writing tiny code");
  1259. output.Write((byte)headerFlags);
  1260. } else {
  1261. // Console.WriteLine("Writing fat code");
  1262. output.Write(headerFlags);
  1263. output.Write((ushort)maxStack);
  1264. output.Write(offset);
  1265. output.Write(localSigIx);
  1266. }
  1267. // Console.WriteLine(Hex.Int(tide) + " CIL instructions");
  1268. // Console.WriteLine("starting instructions at " + output.Seek(0,SeekOrigin.Current));
  1269. for (int i=0; i < tide; i++) {
  1270. buffer[i].Write(output);
  1271. }
  1272. // Console.WriteLine("ending instructions at " + output.Seek(0,SeekOrigin.Current));
  1273. for (int i=0; i < paddingNeeded; i++) { output.Write((byte)0); }
  1274. if (exceptions != null) {
  1275. // Console.WriteLine("Writing exceptions");
  1276. // Console.WriteLine("header = " + Hex.Short(exceptHeader) + " exceptSize = " + Hex.Int(exceptSize));
  1277. output.Write(exceptHeader);
  1278. output.Write3Bytes((uint)exceptSize);
  1279. for (int i=0; i < exceptions.Count; i++) {
  1280. TryBlock tryBlock = (TryBlock)exceptions[i];
  1281. tryBlock.Write(output,fatExceptionFormat);
  1282. }
  1283. }
  1284. }
  1285. }
  1286. /**************************************************************************/
  1287. /// <summary>
  1288. /// A label in the IL
  1289. /// </summary>
  1290. public class CILLabel
  1291. {
  1292. CILInstruction branch;
  1293. CILInstruction[] multipleBranches;
  1294. int tide = 0;
  1295. CILInstruction labInstr;
  1296. uint offset = 0;
  1297. public CILLabel (uint offset) {
  1298. this.offset = offset;
  1299. }
  1300. internal CILLabel() {
  1301. }
  1302. internal void AddBranch(CILInstruction instr) {
  1303. if (branch == null) {
  1304. branch = instr;
  1305. return;
  1306. }
  1307. if (multipleBranches == null) {
  1308. multipleBranches = new CILInstruction[2];
  1309. } else if (tide >= multipleBranches.Length) {
  1310. CILInstruction[] tmp = multipleBranches;
  1311. multipleBranches = new CILInstruction[tmp.Length*2];
  1312. for (int i=0; i < tide; i++) {
  1313. multipleBranches[i] = tmp[i];
  1314. }
  1315. }
  1316. multipleBranches[tide++] = instr;
  1317. }
  1318. internal void AddLabelInstr(LabelInstr lInstr) {
  1319. labInstr = lInstr;
  1320. }
  1321. internal uint GetLabelOffset() {
  1322. if (labInstr == null) return 0;
  1323. return labInstr.offset + offset;
  1324. }
  1325. }
  1326. /**************************************************************************/
  1327. public abstract class CodeBlock {
  1328. private static readonly int maxCodeSize = 256;
  1329. protected CILLabel start, end;
  1330. protected bool small = true;
  1331. public CodeBlock(CILLabel start, CILLabel end) {
  1332. this.start = start;
  1333. this.end = end;
  1334. }
  1335. internal virtual bool isFat() {
  1336. // Console.WriteLine("block start = " + start.GetLabelOffset() +
  1337. // " block end = " + end.GetLabelOffset());
  1338. return (end.GetLabelOffset() - start.GetLabelOffset()) > maxCodeSize;
  1339. }
  1340. internal virtual void Write(FileImage output, bool fatFormat) {
  1341. if (fatFormat) output.Write(start.GetLabelOffset());
  1342. else output.Write((short)start.GetLabelOffset());
  1343. uint len = end.GetLabelOffset() - start.GetLabelOffset();
  1344. if (fatFormat) output.Write(len);
  1345. else output.Write((byte)len);
  1346. }
  1347. }
  1348. /// <summary>
  1349. /// The descriptor for a guarded block (.try)
  1350. /// </summary>
  1351. public class TryBlock : CodeBlock {
  1352. protected bool fatFormat = false;
  1353. protected int flags = 0;
  1354. ArrayList handlers = new ArrayList();
  1355. /// <summary>
  1356. /// Create a new try block
  1357. /// </summary>
  1358. /// <param name="start">start label for the try block</param>
  1359. /// <param name="end">end label for the try block</param>
  1360. public TryBlock(CILLabel start, CILLabel end) : base(start,end) { }
  1361. /// <summary>
  1362. /// Add a handler to this try block
  1363. /// </summary>
  1364. /// <param name="handler">a handler to be added to the try block</param>
  1365. public void AddHandler(HandlerBlock handler) {
  1366. flags = handler.GetFlag();
  1367. handlers.Add(handler);
  1368. }
  1369. internal void SetSize() {
  1370. fatFormat = base.isFat();
  1371. if (fatFormat) return;
  1372. for (int i=0; i < handlers.Count; i++) {
  1373. HandlerBlock handler = (HandlerBlock)handlers[i];
  1374. if (handler.isFat()) {
  1375. fatFormat = true;
  1376. return;
  1377. }
  1378. }
  1379. }
  1380. internal int NumHandlers() {
  1381. return handlers.Count;
  1382. }
  1383. internal override bool isFat() {
  1384. return fatFormat;
  1385. }
  1386. internal override void Write(FileImage output, bool fatFormat) {
  1387. // Console.WriteLine("writing exception details");
  1388. for (int i=0; i < handlers.Count; i++) {
  1389. // Console.WriteLine("Except block " + i);
  1390. HandlerBlock handler = (HandlerBlock)handlers[i];
  1391. if (fatFormat) output.Write(flags);
  1392. else output.Write((short)flags);
  1393. // Console.WriteLine("flags = " + Hex.Short(flags));
  1394. base.Write(output,fatFormat);
  1395. handler.Write(output,fatFormat);
  1396. }
  1397. }
  1398. }
  1399. public abstract class HandlerBlock : CodeBlock
  1400. {
  1401. protected static readonly short ExceptionFlag = 0;
  1402. protected static readonly short FilterFlag = 0x01;
  1403. protected static readonly short FinallyFlag = 0x02;
  1404. protected static readonly short FaultFlag = 0x04;
  1405. public HandlerBlock(CILLabel start, CILLabel end) : base(start,end) { }
  1406. internal virtual short GetFlag() { return ExceptionFlag; }
  1407. internal override void Write(FileImage output, bool fatFormat) {
  1408. base.Write(output,fatFormat);
  1409. }
  1410. }
  1411. /// <summary>
  1412. /// The descriptor for a catch clause (.catch)
  1413. /// </summary>
  1414. public class Catch : HandlerBlock
  1415. {
  1416. Class exceptType;
  1417. /// <summary>
  1418. /// Create a new catch clause
  1419. /// </summary>
  1420. /// <param name="except">the exception to be caught</param>
  1421. /// <param name="handlerStart">start of the handler code</param>
  1422. /// <param name="handlerEnd">end of the handler code</param>
  1423. public Catch(Class except, CILLabel handlerStart, CILLabel handlerEnd)
  1424. : base(handlerStart,handlerEnd) {
  1425. exceptType = except;
  1426. }
  1427. internal override void Write(FileImage output, bool fatFormat) {
  1428. base.Write(output,fatFormat);
  1429. output.Write(exceptType.Token());
  1430. }
  1431. }
  1432. /// <summary>
  1433. /// The descriptor for a filter clause (.filter)
  1434. /// </summary>
  1435. public class Filter : HandlerBlock
  1436. {
  1437. CILLabel filterLabel;
  1438. /// <summary>
  1439. /// Create a new filter clause
  1440. /// </summary>
  1441. /// <param name="filterLabel">the label where the filter code starts</param>
  1442. /// <param name="handlerStart">the start of the handler code</param>
  1443. /// <param name="handlerEnd">the end of the handler code</param>
  1444. public Filter(CILLabel filterLabel, CILLabel handlerStart,
  1445. CILLabel handlerEnd) : base(handlerStart,handlerEnd) {
  1446. this.filterLabel = filterLabel;
  1447. }
  1448. internal override short GetFlag() {
  1449. return FilterFlag;
  1450. }
  1451. internal override void Write(FileImage output, bool fatFormat) {
  1452. base.Write(output,fatFormat);
  1453. output.Write(filterLabel.GetLabelOffset());
  1454. }
  1455. }
  1456. /// <summary>
  1457. /// Descriptor for a finally block (.finally)
  1458. /// </summary>
  1459. public class Finally : HandlerBlock
  1460. {
  1461. /// <summary>
  1462. /// Create a new finally clause
  1463. /// </summary>
  1464. /// <param name="finallyStart">start of finally code</param>
  1465. /// <param name="finallyEnd">end of finally code</param>
  1466. public Finally(CILLabel finallyStart, CILLabel finallyEnd)
  1467. : base(finallyStart,finallyEnd) { }
  1468. internal override short GetFlag() {
  1469. return FinallyFlag;
  1470. }
  1471. internal override void Write(FileImage output, bool fatFormat) {
  1472. base.Write(output,fatFormat);
  1473. output.Write((int)0);
  1474. }
  1475. }
  1476. /// <summary>
  1477. /// Descriptor for a fault block (.fault)
  1478. /// </summary>
  1479. public class Fault : HandlerBlock
  1480. {
  1481. /// <summary>
  1482. /// Create a new fault clause
  1483. /// </summary>
  1484. /// <param name="faultStart">start of the fault code</param>
  1485. /// <param name="faultEnd">end of the fault code</param>
  1486. public Fault(CILLabel faultStart, CILLabel faultEnd)
  1487. : base(faultStart,faultEnd) { }
  1488. internal override short GetFlag() {
  1489. return FaultFlag;
  1490. }
  1491. internal override void Write(FileImage output, bool fatFormat) {
  1492. base.Write(output,fatFormat);
  1493. output.Write((int)0);
  1494. }
  1495. }
  1496. /**************************************************************************/
  1497. /// <summary>
  1498. /// The base descriptor for a class
  1499. /// </summary>
  1500. public abstract class Class : Type
  1501. {
  1502. protected int row = 0;
  1503. protected string name, nameSpace;
  1504. protected uint nameIx, nameSpaceIx;
  1505. protected MetaData _metaData;
  1506. internal Class(string nameSpaceName, string className, MetaData md)
  1507. : base(0x12) {
  1508. nameSpace = nameSpaceName;
  1509. name = className;
  1510. nameIx = md.AddToStringsHeap(name);
  1511. nameSpaceIx = md.AddToStringsHeap(nameSpace);
  1512. _metaData = md;
  1513. }
  1514. internal Class(uint nsIx, uint nIx) : base(0x12) {
  1515. nameSpaceIx = nsIx;
  1516. nameIx = nIx;
  1517. }
  1518. internal virtual uint TypeDefOrRefToken() { return 0; }
  1519. internal virtual void MakeValueClass() {
  1520. typeIndex = 0x11;
  1521. }
  1522. internal virtual string TypeName() {
  1523. return (nameSpace + "." + name);
  1524. }
  1525. internal override MetaDataElement GetTypeSpec(MetaData md) {
  1526. return this;
  1527. }
  1528. }
  1529. /**************************************************************************/
  1530. // This Class produces entries in the TypeDef table of the MetaData
  1531. // in the PE meta data.
  1532. // NOTE: Entry 0 in TypeDef table is always the pseudo class <module>
  1533. // which is the parent for functions and variables declared a module level
  1534. /// <summary>
  1535. /// The descriptor for a class defined in the IL (.class) in the current assembly/module
  1536. /// </summary>
  1537. ///
  1538. public class ClassDef : Class
  1539. {
  1540. private static readonly uint HasSecurity = 0x00040000;
  1541. private static readonly byte ElementType_Class = 0x12;
  1542. Class superType;
  1543. ArrayList fields = new ArrayList();
  1544. ArrayList methods = new ArrayList();
  1545. ArrayList events;
  1546. ArrayList properties;
  1547. bool typeIndexChecked = true;
  1548. uint fieldIx = 0, methodIx = 0;
  1549. byte[] securityActions;
  1550. uint flags;
  1551. ClassLayout layout;
  1552. ClassDef parentClass;
  1553. MetaData metaData;
  1554. internal ClassDef(TypeAttr attrSet, string nsName, string name,
  1555. MetaData md) : base(nsName, name, md) {
  1556. metaData = md;
  1557. superType = metaData.mscorlib.GetSpecialSystemClass(PrimitiveType.Object);
  1558. flags = (uint)attrSet;
  1559. tabIx = MDTable.TypeDef;
  1560. }
  1561. internal void SetSuper(Class sClass) {
  1562. superType = sClass;
  1563. if (sClass is ClassRef)
  1564. typeIndex = superType.GetTypeIndex();
  1565. else
  1566. typeIndexChecked = false;
  1567. }
  1568. internal override void MakeValueClass() {
  1569. superType = metaData.mscorlib.ValueType();
  1570. typeIndex = superType.GetTypeIndex();
  1571. }
  1572. public void SpecialNoSuper() {
  1573. superType = null;
  1574. }
  1575. /// <summary>
  1576. /// Add an attribute to this class
  1577. /// </summary>
  1578. /// <param name="ta">the attribute to be added</param>
  1579. public void AddAttribute(TypeAttr ta) {
  1580. flags |= (uint)ta;
  1581. }
  1582. /// <summary>
  1583. /// Add an interface that is implemented by this class
  1584. /// </summary>
  1585. /// <param name="iFace">the interface that is implemented</param>
  1586. public void AddImplementedInterface(Class iFace) {
  1587. metaData.AddToTable(MDTable.InterfaceImpl,new InterfaceImpl(this,iFace));
  1588. }
  1589. /// <summary>
  1590. /// Add a named generic type parameter
  1591. /// </summary>
  1592. public GenericParameter AddGenericParameter (short index, string name) {
  1593. GenericParameter gp = new GenericParameter (this, metaData, index, name);
  1594. metaData.AddToTable (MDTable.GenericParam, gp);
  1595. return gp;
  1596. }
  1597. /// <summary>
  1598. /// Add a field to this class
  1599. /// </summary>
  1600. /// <param name="name">field name</param>
  1601. /// <param name="fType">field type</param>
  1602. /// <returns>a descriptor for this new field</returns>
  1603. public FieldDef AddField(string name, Type fType) {
  1604. FieldDef field = new FieldDef(name,fType);
  1605. fields.Add(field);
  1606. return field;
  1607. }
  1608. /// <summary>
  1609. /// Add a field to this class
  1610. /// </summary>
  1611. /// <param name="fAtts">attributes for this field</param>
  1612. /// <param name="name">field name</param>
  1613. /// <param name="fType">field type</param>
  1614. /// <returns>a descriptor for this new field</returns>
  1615. public FieldDef AddField(FieldAttr fAtts, string name, Type fType) {
  1616. FieldDef field = new FieldDef(fAtts,name,fType);
  1617. fields.Add(field);
  1618. return field;
  1619. }
  1620. public void SetFieldOrder (ArrayList fields)
  1621. {
  1622. this.fields = fields;
  1623. }
  1624. /// <summary>
  1625. /// Add a method to this class
  1626. /// </summary>
  1627. /// <param name="name">method name</param>
  1628. /// <param name="retType">return type</param>
  1629. /// <param name="pars">parameters</param>
  1630. /// <returns>a descriptor for this new method</returns>
  1631. public MethodDef AddMethod(string name, Type retType, Param[] pars) {
  1632. // Console.WriteLine("Adding method " + name + " to class " + this.name);
  1633. MethodDef meth = new MethodDef(metaData,name,retType, pars);
  1634. methods.Add(meth);
  1635. return meth;
  1636. }
  1637. /// <summary>
  1638. /// Add a method to this class
  1639. /// </summary>
  1640. /// <param name="mAtts">attributes for this method</param>
  1641. /// <param name="iAtts">implementation attributes for this method</param>
  1642. /// <param name="name">method name</param>
  1643. /// <param name="retType">return type</param>
  1644. /// <param name="pars">parameters</param>
  1645. /// <returns>a descriptor for this new method</returns>
  1646. public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name,
  1647. Type retType, Param[] pars) {
  1648. // Console.WriteLine("Adding method " + name + " to class " + this.name);
  1649. MethodDef meth = new MethodDef(metaData,mAtts,iAtts,name,retType,pars);
  1650. methods.Add(meth);
  1651. return meth;
  1652. }
  1653. /// <summary>
  1654. /// Add an event to this class
  1655. /// </summary>
  1656. /// <param name="name">event name</param>
  1657. /// <param name="eType">event type</param>
  1658. /// <returns>a descriptor for this new event</returns>
  1659. public Event AddEvent(string name, Type eType) {
  1660. Event e = new Event(name,eType,this);
  1661. if (events == null) events = new ArrayList();
  1662. events.Add(e);
  1663. return e;
  1664. }
  1665. /// <summary>
  1666. /// Add a property to this class
  1667. /// </summary>
  1668. /// <param name="name">property name</param>
  1669. /// <param name="propType">property type</param>
  1670. /// <returns>a descriptor for this new property</returns>
  1671. public Property AddProperty(string name, Type retType, Type[] pars) {
  1672. Property p = new Property(name, retType, pars, this);
  1673. if (properties == null) properties = new ArrayList();
  1674. properties.Add(p);
  1675. return p;
  1676. }
  1677. /// <summary>
  1678. /// Add a nested class to this class
  1679. /// </summary>
  1680. /// <param name="attrSet">attributes for this nested class</param>
  1681. /// <param name="nsName">nested name space name</param>
  1682. /// <param name="name">nested class name</param>
  1683. /// <returns>a descriptor for this new nested class</returns>
  1684. public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
  1685. string name) {
  1686. ClassDef nClass = new ClassDef(attrSet,nsName,name,metaData);
  1687. metaData.AddToTable(MDTable.TypeDef,nClass);
  1688. metaData.AddToTable(MDTable.NestedClass,new MapElem(nClass,Row,MDTable.TypeDef));
  1689. nClass.parentClass = this;
  1690. return (nClass);
  1691. }
  1692. /// <summary>
  1693. /// Add a nested class to this class
  1694. /// </summary>
  1695. /// <param name="attrSet">attributes for this nested class</param>
  1696. /// <param name="nsName">nested name space name</param>
  1697. /// <param name="name">nested class name</param>
  1698. /// <param name="sType">super type of this nested class</param>
  1699. /// <returns>a descriptor for this new nested class</returns>
  1700. public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
  1701. string name, Class sType) {
  1702. ClassDef nClass = new ClassDef(attrSet,nsName,name,metaData);
  1703. nClass.SetSuper(sType);
  1704. metaData.AddToTable(MDTable.TypeDef,nClass);
  1705. metaData.AddToTable(MDTable.NestedClass,
  1706. new MapElem(nClass,Row,MDTable.TypeDef));
  1707. nClass.parentClass = this;
  1708. return (nClass);
  1709. }
  1710. /// <summary>
  1711. /// Add layout information for this class. This class must have the
  1712. /// sequential or explicit attribute.
  1713. /// </summary>
  1714. /// <param name="packSize">packing size (.pack)</param>
  1715. /// <param name="classSize">class size (.size)</param>
  1716. public void AddLayoutInfo (int packSize, int classSize) {
  1717. layout = new ClassLayout(packSize,classSize,this);
  1718. }
  1719. /// <summary>
  1720. /// Use a method as the implementation for another method (.override)
  1721. /// </summary>
  1722. /// <param name="decl">the method to be overridden</param>
  1723. /// <param name="body">the implementation to be used</param>
  1724. public void AddMethodOverride(Method decl, Method body) {
  1725. metaData.AddToTable(MDTable.MethodImpl,new MethodImpl(this,decl,body));
  1726. }
  1727. /// <summary>
  1728. /// Add security to this class NOT YET IMPLEMENTED
  1729. /// </summary>
  1730. /// <param name="permissionSet"></param>
  1731. public void AddSecurity(byte[] permissionSet) {
  1732. throw(new NotYetImplementedException("Class security "));
  1733. //flags |= HasSecurity;
  1734. // securityActions = permissionSet;
  1735. }
  1736. //public void AddLineInfo(int row, int col) { }
  1737. internal void CheckTypeIndex() {
  1738. if (typeIndexChecked) return;
  1739. if (!(superType is ClassRef))
  1740. ((ClassDef)superType).CheckTypeIndex();
  1741. typeIndex = superType.GetTypeIndex();
  1742. typeIndexChecked = true;
  1743. }
  1744. internal sealed override void BuildTables(MetaData md) {
  1745. if (done) return;
  1746. if ((flags & (uint)TypeAttr.Interface) != 0) { superType = null; }
  1747. // Console.WriteLine("Building tables for " + name);
  1748. if (layout != null) md.AddToTable(MDTable.ClassLayout,layout);
  1749. // Console.WriteLine("adding methods " + methods.Count);
  1750. methodIx = md.TableIndex(MDTable.Method);
  1751. for (int i=0; i < methods.Count; i++) {
  1752. md.AddToTable(MDTable.Method,(MetaDataElement)methods[i]);
  1753. ((MethodDef)methods[i]).BuildTables(md);
  1754. }
  1755. // Console.WriteLine("adding fields");
  1756. fieldIx = md.TableIndex(MDTable.Field);
  1757. for (int i=0; i < fields.Count; i++) {
  1758. md.AddToTable(MDTable.Field,(MetaDataElement)fields[i]);
  1759. ((FieldDef)fields[i]).BuildTables(md);
  1760. }
  1761. // Console.WriteLine("adding events and properties");
  1762. if (events != null) {
  1763. for (int i=0; i < events.Count; i++) {
  1764. md.AddToTable(MDTable.Event,(Event)events[i]);
  1765. ((Event)events[i]).BuildTables(md);
  1766. }
  1767. md.AddToTable(MDTable.EventMap,
  1768. new MapElem(this,((Event)events[0]).Row,MDTable.Event));
  1769. }
  1770. if (properties != null) {
  1771. for (int i=0; i < properties.Count; i++) {
  1772. md.AddToTable(MDTable.Property,(Property)properties[i]);
  1773. ((Property)properties[i]).BuildTables(md);
  1774. }
  1775. md.AddToTable(MDTable.PropertyMap,new MapElem(this,
  1776. ((Property)properties[0]).Row,MDTable.Property));
  1777. }
  1778. // Console.WriteLine("End of building tables");
  1779. done = true;
  1780. }
  1781. internal sealed override uint Size(MetaData md) {
  1782. return 4 + 2 * md.StringsIndexSize() +
  1783. md.CodedIndexSize(CIx.TypeDefOrRef) +
  1784. md.TableIndexSize(MDTable.Field) +
  1785. md.TableIndexSize(MDTable.Method);
  1786. }
  1787. internal sealed override void Write(FileImage output) {
  1788. output.Write(flags);
  1789. output.StringsIndex(nameIx);
  1790. output.StringsIndex(nameSpaceIx);
  1791. //if (superType != null)
  1792. // Console.WriteLine("getting coded index for superType of " + name + " = " + superType.GetCodedIx(CIx.TypeDefOrRef));
  1793. output.WriteCodedIndex(CIx.TypeDefOrRef,superType);
  1794. output.WriteIndex(MDTable.Field,fieldIx);
  1795. output.WriteIndex(MDTable.Method,methodIx);
  1796. }
  1797. internal sealed override uint TypeDefOrRefToken() {
  1798. uint cIx = Row;
  1799. cIx = cIx << 2;
  1800. return cIx;
  1801. }
  1802. internal sealed override void TypeSig(MemoryStream sig) {
  1803. if (!typeIndexChecked) CheckTypeIndex();
  1804. sig.WriteByte(GetTypeIndex());
  1805. MetaData.CompressNum(TypeDefOrRefToken(),sig);
  1806. }
  1807. internal sealed override uint GetCodedIx(CIx code) {
  1808. switch (code) {
  1809. case (CIx.TypeDefOrRef) : return 0;
  1810. case (CIx.HasCustomAttr) : return 3;
  1811. case (CIx.HasDeclSecurity) : return 0;
  1812. case (CIx.TypeOrMethodDef) : return 0;
  1813. }
  1814. return 0;
  1815. }
  1816. }
  1817. /**************************************************************************/
  1818. /// <summary>
  1819. /// Layout information for a class (.class [sequential | explicit])
  1820. /// </summary>
  1821. internal class ClassLayout : MetaDataElement
  1822. {
  1823. ClassDef parent;
  1824. ushort packSize = 0;
  1825. uint classSize = 0;
  1826. internal ClassLayout(int pack, int cSize, ClassDef par) {
  1827. packSize = (ushort)pack;
  1828. classSize = (uint)cSize;
  1829. parent = par;
  1830. tabIx = MDTable.ClassLayout;
  1831. }
  1832. internal sealed override uint Size(MetaData md) {
  1833. return 6 + md.TableIndexSize(MDTable.TypeDef);
  1834. }
  1835. internal sealed override void Write(FileImage output) {
  1836. output.Write(packSize);
  1837. output.Write(classSize);
  1838. output.WriteIndex(MDTable.TypeDef,parent.Row);
  1839. }
  1840. }
  1841. /**************************************************************************/
  1842. /// <summary>
  1843. /// Descriptor for a class/interface declared in another module of THIS
  1844. /// assembly, or in another assembly.
  1845. /// </summary>
  1846. public class ClassRef : Class
  1847. {
  1848. protected ResolutionScope parent;
  1849. ExternClass externClass;
  1850. protected MetaData metaData;
  1851. internal ClassRef(string nsName, string name, MetaData md) : base(nsName, name, md) {
  1852. metaData = md;
  1853. tabIx = MDTable.TypeRef;
  1854. }
  1855. /// <summary>
  1856. /// Add a method to this class
  1857. /// </summary>
  1858. /// <param name="name">method name</param>
  1859. /// <param name="retType">return type</param>
  1860. /// <param name="pars">parameter types</param>
  1861. /// <returns>a descriptor for this method</returns>
  1862. public MethodRef AddMethod(string name, Type retType, Type[] pars) {
  1863. MethodRef meth = new MethodRef(this,name,retType,pars,false,null);
  1864. metaData.AddToTable(MDTable.MemberRef,meth);
  1865. return meth;
  1866. }
  1867. /// <summary>
  1868. /// Add a method to this class
  1869. /// </summary>
  1870. /// <param name="name">method name</param>
  1871. /// <param name="retType">return type</param>
  1872. /// <param name="pars">parameter types</param>
  1873. /// <returns>a descriptor for this method</returns>
  1874. public MethodRef AddVarArgMethod(string name, Type retType,
  1875. Type[] pars, Type[] optPars) {
  1876. MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars);
  1877. metaData.AddToTable(MDTable.MemberRef,meth);
  1878. return meth;
  1879. }
  1880. /// <summary>
  1881. /// Add a field to this class
  1882. /// </summary>
  1883. /// <param name="name">field name</param>
  1884. /// <param name="fType">field type</param>
  1885. /// <returns>a descriptor for this field</returns>
  1886. public FieldRef AddField(string name, Type fType) {
  1887. FieldRef field = new FieldRef(this,name,fType);
  1888. metaData.AddToTable(MDTable.MemberRef,field);
  1889. return field;
  1890. }
  1891. internal void SetParent(ResolutionScope par) {
  1892. parent = par;
  1893. }
  1894. internal override string TypeName() {
  1895. if ((parent != null) && (parent is AssemblyRef))
  1896. return (nameSpace + "." + name + ", " + ((AssemblyRef)parent).TypeName());
  1897. else
  1898. return (nameSpace + name);
  1899. }
  1900. internal sealed override uint Size(MetaData md) {
  1901. return md.CodedIndexSize(CIx.ResolutionScope) + 2 *
  1902. md.StringsIndexSize();
  1903. }
  1904. internal sealed override void Write(FileImage output) {
  1905. output.WriteCodedIndex(CIx.ResolutionScope,parent);
  1906. output.StringsIndex(nameIx);
  1907. output.StringsIndex(nameSpaceIx);
  1908. }
  1909. internal override sealed uint TypeDefOrRefToken() {
  1910. uint cIx = Row;
  1911. cIx = (cIx << 2) | 0x1;
  1912. return cIx;
  1913. }
  1914. internal override void TypeSig(MemoryStream sig) {
  1915. sig.WriteByte(GetTypeIndex());
  1916. MetaData.CompressNum(TypeDefOrRefToken(),sig);
  1917. }
  1918. internal sealed override uint GetCodedIx(CIx code) {
  1919. switch (code) {
  1920. case (CIx.TypeDefOrRef) : return 1;
  1921. case (CIx.HasCustomAttr) : return 2;
  1922. case (CIx.MemberRefParent) : return 1;
  1923. case (CIx.ResolutionScope) : return 3;
  1924. }
  1925. return 0;
  1926. }
  1927. }
  1928. /**************************************************************************/
  1929. public class ExternClassRef : ClassRef {
  1930. ExternClass externClass;
  1931. internal ExternClassRef(TypeAttr attrs, string nsName, string name,
  1932. FileRef declFile, MetaData md) : base(nsName,name,md) {
  1933. externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declFile);
  1934. metaData.AddToTable(MDTable.ExportedType,externClass);
  1935. }
  1936. internal ExternClassRef(string name, MetaData md) : base(null,name,md) {
  1937. }
  1938. public ClassRef AddNestedClass(TypeAttr attrs, string name) {
  1939. ExternClassRef nestedClass = new ExternClassRef(name,metaData);
  1940. externClass = new ExternClass(attrs,0,nameIx,this.externClass);
  1941. metaData.AddToTable(MDTable.ExportedType,externClass);
  1942. return nestedClass;
  1943. }
  1944. }
  1945. /**************************************************************************/
  1946. /// <summary>
  1947. /// Descriptor for a constant value
  1948. /// </summary>
  1949. public abstract class Constant {
  1950. protected uint size = 0;
  1951. protected Type type;
  1952. protected uint blobIndex;
  1953. protected bool addedToBlobHeap = false;
  1954. internal Constant() { }
  1955. internal virtual uint GetBlobIndex(MetaData md) { return 0; }
  1956. internal uint GetSize() { return size; }
  1957. internal byte GetTypeIndex() { return type.GetTypeIndex(); }
  1958. internal virtual void Write(BinaryWriter bw) { }
  1959. }
  1960. /// <summary>
  1961. /// Descriptor for a constant value
  1962. /// </summary>
  1963. public abstract class DataConstant : Constant {
  1964. private uint dataOffset = 0;
  1965. internal DataConstant() { }
  1966. public uint DataOffset {
  1967. get { return dataOffset; }
  1968. set { dataOffset = value; }
  1969. }
  1970. }
  1971. /// <summary>
  1972. /// Boolean constant
  1973. /// </summary>
  1974. public class BoolConst : Constant {
  1975. bool val;
  1976. /// <summary>
  1977. /// Create a new boolean constant with the value "val"
  1978. /// </summary>
  1979. /// <param name="val">value of this boolean constant</param>
  1980. public BoolConst(bool val) {
  1981. this.val = val;
  1982. size = 1;
  1983. type = PrimitiveType.Boolean;
  1984. }
  1985. internal sealed override uint GetBlobIndex(MetaData md) {
  1986. if (!addedToBlobHeap) {
  1987. if (val) blobIndex = md.AddToBlobHeap((sbyte)1);
  1988. else blobIndex = md.AddToBlobHeap((sbyte)0);
  1989. addedToBlobHeap = true;
  1990. }
  1991. return blobIndex;
  1992. }
  1993. internal sealed override void Write(BinaryWriter bw) {
  1994. if (val) bw.Write((sbyte)1);
  1995. else bw.Write((sbyte)0);
  1996. }
  1997. }
  1998. public class ByteArrConst : DataConstant {
  1999. byte[] val;
  2000. public ByteArrConst(byte[] val) {
  2001. this.val = val;
  2002. size = (uint)val.Length;
  2003. }
  2004. public Type Type {
  2005. get { return type; }
  2006. set { type = value; }
  2007. }
  2008. internal sealed override uint GetBlobIndex(MetaData md) {
  2009. if (!addedToBlobHeap) {
  2010. blobIndex = md.AddToBlobHeap(val);
  2011. addedToBlobHeap = true;
  2012. }
  2013. return blobIndex;
  2014. }
  2015. internal sealed override void Write(BinaryWriter bw) {
  2016. bw.Write(val);
  2017. }
  2018. }
  2019. public class CharConst : Constant {
  2020. char val;
  2021. public CharConst(char val) {
  2022. this.val = val;
  2023. size = 2;
  2024. type = PrimitiveType.Char;
  2025. }
  2026. internal sealed override uint GetBlobIndex(MetaData md) {
  2027. if (!addedToBlobHeap) {
  2028. blobIndex = md.AddToBlobHeap(val);
  2029. addedToBlobHeap = true;
  2030. }
  2031. return blobIndex;
  2032. }
  2033. internal sealed override void Write(BinaryWriter bw) {
  2034. bw.Write(val);
  2035. }
  2036. }
  2037. public class FloatConst : DataConstant {
  2038. float val;
  2039. public FloatConst(float val) {
  2040. this.val = val;
  2041. size = 4;
  2042. type = PrimitiveType.Float32;
  2043. }
  2044. internal sealed override uint GetBlobIndex(MetaData md) {
  2045. if (!addedToBlobHeap) {
  2046. blobIndex = md.AddToBlobHeap(val);
  2047. addedToBlobHeap = true;
  2048. }
  2049. return blobIndex;
  2050. }
  2051. internal sealed override void Write(BinaryWriter bw) {
  2052. bw.Write(val);
  2053. }
  2054. }
  2055. public class DoubleConst : DataConstant {
  2056. double val;
  2057. public DoubleConst(double val) {
  2058. this.val = val;
  2059. size = 8;
  2060. type = PrimitiveType.Float64;
  2061. }
  2062. internal sealed override uint GetBlobIndex(MetaData md) {
  2063. if (!addedToBlobHeap) {
  2064. blobIndex = md.AddToBlobHeap(val);
  2065. addedToBlobHeap = true;
  2066. }
  2067. return blobIndex;
  2068. }
  2069. internal sealed override void Write(BinaryWriter bw) {
  2070. bw.Write(val);
  2071. }
  2072. }
  2073. public class IntConst : DataConstant {
  2074. long val;
  2075. public IntConst(sbyte val) {
  2076. this.val = val;
  2077. size = 1;
  2078. type = PrimitiveType.Int8;
  2079. }
  2080. public IntConst(short val) {
  2081. this.val = val;
  2082. size = 2;
  2083. type = PrimitiveType.Int16;
  2084. }
  2085. public IntConst(int val) {
  2086. this.val = val;
  2087. size = 4;
  2088. type = PrimitiveType.Int32;
  2089. }
  2090. public IntConst(long val) {
  2091. this.val = val;
  2092. size = 8;
  2093. type = PrimitiveType.Int64;
  2094. }
  2095. internal sealed override uint GetBlobIndex(MetaData md) {
  2096. if (!addedToBlobHeap) {
  2097. switch (size) {
  2098. case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
  2099. case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
  2100. case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
  2101. default : blobIndex = md.AddToBlobHeap(val); break;
  2102. }
  2103. addedToBlobHeap = true;
  2104. }
  2105. return blobIndex;
  2106. }
  2107. internal sealed override void Write(BinaryWriter bw) {
  2108. switch (size) {
  2109. case (1) : bw.Write((sbyte)val); break;
  2110. case (2) : bw.Write((short)val); break;
  2111. case (4) : bw.Write((int)val); break;
  2112. default : bw.Write(val); break;
  2113. }
  2114. }
  2115. }
  2116. public class UIntConst : Constant {
  2117. long val;
  2118. public UIntConst(sbyte val) {
  2119. this.val = val;
  2120. size = 1;
  2121. type = PrimitiveType.UInt8;
  2122. }
  2123. public UIntConst(short val) {
  2124. this.val = val;
  2125. size = 2;
  2126. type = PrimitiveType.UInt16;
  2127. }
  2128. public UIntConst(int val) {
  2129. this.val = val;
  2130. size = 4;
  2131. type = PrimitiveType.UInt32;
  2132. }
  2133. public UIntConst(long val) {
  2134. this.val = val;
  2135. size = 8;
  2136. type = PrimitiveType.UInt64;
  2137. }
  2138. internal sealed override uint GetBlobIndex(MetaData md) {
  2139. if (!addedToBlobHeap) {
  2140. switch (size) {
  2141. case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
  2142. case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
  2143. case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
  2144. default : blobIndex = md.AddToBlobHeap(val); break;
  2145. }
  2146. addedToBlobHeap = true;
  2147. }
  2148. return blobIndex;
  2149. }
  2150. internal sealed override void Write(BinaryWriter bw) {
  2151. switch (size) {
  2152. case (1) : bw.Write((sbyte)val); break;
  2153. case (2) : bw.Write((short)val); break;
  2154. case (4) : bw.Write((int)val); break;
  2155. default : bw.Write(val); break;
  2156. }
  2157. }
  2158. }
  2159. public class StringConst : DataConstant {
  2160. string val;
  2161. public StringConst(string val) {
  2162. this.val = val;
  2163. size = (uint)val.Length; // need to add null ??
  2164. type = PrimitiveType.String;
  2165. }
  2166. internal sealed override uint GetBlobIndex(MetaData md) {
  2167. if (!addedToBlobHeap) {
  2168. byte [] b = Encoding.Unicode.GetBytes (val);
  2169. blobIndex = md.AddToBlobHeap(b);
  2170. addedToBlobHeap = true;
  2171. }
  2172. return blobIndex;
  2173. }
  2174. internal sealed override void Write(BinaryWriter bw) {
  2175. bw.Write(val);
  2176. }
  2177. }
  2178. public class NullConst : Constant {
  2179. public NullConst() {
  2180. size = 4;
  2181. type = PrimitiveType.Class;
  2182. }
  2183. internal sealed override uint GetBlobIndex(MetaData md) {
  2184. if (!addedToBlobHeap) {
  2185. blobIndex = md.AddToBlobHeap((int)0);
  2186. addedToBlobHeap = true;
  2187. }
  2188. return blobIndex;
  2189. }
  2190. internal sealed override void Write(BinaryWriter bw) {
  2191. bw.Write((int)0);
  2192. }
  2193. }
  2194. public class AddressConstant : DataConstant {
  2195. DataConstant data;
  2196. public AddressConstant(DataConstant dConst) {
  2197. data = dConst;
  2198. size = 4;
  2199. type = PrimitiveType.TypedRef;
  2200. }
  2201. internal sealed override void Write(BinaryWriter bw) {
  2202. ((FileImage)bw).WriteDataRVA(data.DataOffset);
  2203. }
  2204. }
  2205. public class RepeatedConstant : DataConstant {
  2206. DataConstant data;
  2207. uint repCount;
  2208. public RepeatedConstant(DataConstant dConst, int repeatCount) {
  2209. data = dConst;
  2210. repCount = (uint)repeatCount;
  2211. int[] sizes = new int[1];
  2212. sizes[0] = repeatCount;
  2213. type = new BoundArray(type,1,sizes);
  2214. size = data.GetSize() * repCount;
  2215. }
  2216. internal sealed override void Write(BinaryWriter bw) {
  2217. for (int i=0; i < repCount; i++) {
  2218. data.Write(bw);
  2219. }
  2220. }
  2221. }
  2222. public class ArrayConstant : DataConstant {
  2223. DataConstant[] dataVals;
  2224. public ArrayConstant(DataConstant[] dVals) {
  2225. dataVals = dVals;
  2226. for (int i=0; i < dataVals.Length; i++) {
  2227. size += dataVals[i].GetSize();
  2228. }
  2229. }
  2230. internal sealed override void Write(BinaryWriter bw) {
  2231. for (int i=0; i < dataVals.Length; i++) {
  2232. dataVals[i].Write(bw);
  2233. }
  2234. }
  2235. }
  2236. public class ClassType : Constant {
  2237. string name;
  2238. Class desc;
  2239. public ClassType(string className) {
  2240. name = className;
  2241. type = PrimitiveType.ClassType;
  2242. }
  2243. public ClassType(Class classDesc) {
  2244. desc = classDesc;
  2245. type = PrimitiveType.ClassType;
  2246. }
  2247. internal override void Write(BinaryWriter bw) {
  2248. if (name == null) name = desc.TypeName();
  2249. bw.Write(name);
  2250. }
  2251. }
  2252. /**************************************************************************/
  2253. /// <summary>
  2254. /// Summary description for ConstantElem.
  2255. /// </summary>
  2256. internal class ConstantElem : MetaDataElement
  2257. {
  2258. MetaDataElement parent;
  2259. Constant cValue;
  2260. uint valIx = 0;
  2261. internal ConstantElem(MetaDataElement parent, Constant val) {
  2262. this.parent = parent;
  2263. cValue = val;
  2264. tabIx = MDTable.Constant;
  2265. }
  2266. internal sealed override void BuildTables(MetaData md) {
  2267. if (done) return;
  2268. valIx = cValue.GetBlobIndex(md);
  2269. done = true;
  2270. }
  2271. internal void AddToBlob(BinaryWriter bw) {
  2272. cValue.Write(bw);
  2273. }
  2274. internal sealed override uint Size(MetaData md) {
  2275. return 2 + md.CodedIndexSize(CIx.HasConst) + md.BlobIndexSize();
  2276. }
  2277. internal sealed override void Write(FileImage output) {
  2278. output.Write(cValue.GetTypeIndex());
  2279. output.Write((byte)0);
  2280. output.WriteCodedIndex(CIx.HasConst,parent);
  2281. output.BlobIndex(valIx);
  2282. }
  2283. }
  2284. /**************************************************************************/
  2285. /// <summary>
  2286. /// Descriptor for a Custom Attribute (.custom)
  2287. /// </summary>
  2288. public class CustomAttribute : MetaDataElement
  2289. {
  2290. private static readonly ushort prolog = 0x0001;
  2291. MetaDataElement parent;
  2292. Method type;
  2293. uint valIx;
  2294. Constant cVal;
  2295. byte[] byteVal;
  2296. ushort numNamed = 0;
  2297. ArrayList names, vals;
  2298. internal CustomAttribute(MetaDataElement paren, Method constrType,
  2299. Constant val) {
  2300. parent = paren;
  2301. type = constrType;
  2302. cVal = val;
  2303. tabIx = MDTable.CustomAttribute;
  2304. throw(new NotYetImplementedException("Custom Attributes "));
  2305. }
  2306. internal CustomAttribute(MetaDataElement paren, Method constrType,
  2307. byte[] val) {
  2308. parent = paren;
  2309. type = constrType;
  2310. tabIx = MDTable.CustomAttribute;
  2311. byteVal = val;
  2312. }
  2313. public void AddFieldOrProp(string name, Constant val) {
  2314. if (numNamed == 0) {
  2315. names = new ArrayList();
  2316. vals = new ArrayList();
  2317. }
  2318. names.Add(name);
  2319. vals.Add(val);
  2320. }
  2321. internal sealed override void BuildTables(MetaData md) {
  2322. BinaryWriter bw = new BinaryWriter(new MemoryStream());
  2323. bw.Write(byteVal);
  2324. md.AddToTable(MDTable.CustomAttribute, this);
  2325. MemoryStream str = (MemoryStream)bw.BaseStream;
  2326. valIx = md.AddToBlobHeap(str.ToArray());
  2327. }
  2328. internal sealed override uint Size(MetaData md) {
  2329. return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();
  2330. }
  2331. internal sealed override void Write(FileImage output) {
  2332. output.WriteCodedIndex(CIx.HasCustomAttr,parent);
  2333. output.WriteCodedIndex(CIx.CustomAttributeType,type);
  2334. output.BlobIndex(valIx);
  2335. }
  2336. }
  2337. /**************************************************************************/
  2338. /// <summary>
  2339. /// Descriptor for a custom modifier of a type (modopt or modreq)
  2340. /// </summary>
  2341. public class CustomModifiedType : Type
  2342. {
  2343. Type type;
  2344. Class cmodType;
  2345. /// <summary>
  2346. /// Create a new custom modifier for a type
  2347. /// </summary>
  2348. /// <param name="type">the type to be modified</param>
  2349. /// <param name="cmod">the modifier</param>
  2350. /// <param name="cmodType">the type reference to be associated with the type</param>
  2351. public CustomModifiedType(Type type, CustomModifier cmod, Class cmodType)
  2352. : base((byte)cmod) {
  2353. this.type = type;
  2354. this.cmodType = cmodType;
  2355. }
  2356. internal sealed override void TypeSig(MemoryStream str) {
  2357. str.WriteByte(typeIndex);
  2358. MetaData.CompressNum(cmodType.TypeDefOrRefToken(),str);
  2359. type.TypeSig(str);
  2360. }
  2361. }
  2362. /**************************************************************************/
  2363. /// <summary>
  2364. /// Descriptor for security permissions for a class or a method NOT YET IMPLEMENTED
  2365. /// </summary>
  2366. public class DeclSecurity : MetaDataElement
  2367. {
  2368. ushort action;
  2369. MetaDataElement parent;
  2370. uint permissionIx;
  2371. internal DeclSecurity(MetaDataElement paren, ushort act) {
  2372. parent = paren;
  2373. action = act;
  2374. tabIx = MDTable.DeclSecurity;
  2375. throw(new NotYetImplementedException("Security "));
  2376. }
  2377. internal sealed override uint Size(MetaData md) {
  2378. return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();
  2379. }
  2380. internal sealed override void BuildTables(MetaData md) {
  2381. if (done) return;
  2382. // add permission to blob heap
  2383. done = true;
  2384. }
  2385. internal sealed override void Write(FileImage output) {
  2386. output.Write(action);
  2387. output.WriteCodedIndex(CIx.HasDeclSecurity,parent);
  2388. output.BlobIndex(permissionIx);
  2389. }
  2390. }
  2391. /**************************************************************************/
  2392. /// <summary>
  2393. /// Descriptor for an event
  2394. /// </summary>
  2395. public class Event : Feature
  2396. {
  2397. Type eventType;
  2398. internal Event(string name, Type eType, ClassDef parent)
  2399. : base(name, parent) {
  2400. eventType = eType;
  2401. tabIx = MDTable.Event;
  2402. }
  2403. /// <summary>
  2404. /// Add the addon method to this event
  2405. /// </summary>
  2406. /// <param name="addon">the addon method</param>
  2407. public void AddAddon(MethodDef addon) {
  2408. AddMethod(addon,MethodType.AddOn);
  2409. }
  2410. /// <summary>
  2411. /// Add the removeon method to this event
  2412. /// </summary>
  2413. /// <param name="removeOn">the removeon method</param>
  2414. public void AddRemoveOn(MethodDef removeOn) {
  2415. AddMethod(removeOn,MethodType.RemoveOn);
  2416. }
  2417. /// <summary>
  2418. /// Add the fire method to this event
  2419. /// </summary>
  2420. /// <param name="fire">the fire method</param>
  2421. public void AddFire(MethodDef fire) {
  2422. AddMethod(fire,MethodType.Fire);
  2423. }
  2424. /// <summary>
  2425. /// Add another method to this event
  2426. /// </summary>
  2427. /// <param name="other">the method to be added</param>
  2428. public void AddOther(MethodDef other) {
  2429. AddMethod(other,MethodType.Other);
  2430. }
  2431. internal sealed override void BuildTables(MetaData md) {
  2432. if (done) return;
  2433. nameIx = md.AddToStringsHeap(name);
  2434. for (int i=0; i < tide; i++) {
  2435. md.AddToTable(MDTable.MethodSemantics,methods[i]);
  2436. }
  2437. done = true;
  2438. }
  2439. internal sealed override uint Size(MetaData md) {
  2440. return 2 + md.StringsIndexSize() + md.CodedIndexSize(CIx.TypeDefOrRef);
  2441. }
  2442. internal sealed override void Write(FileImage output) {
  2443. output.Write(flags);
  2444. output.StringsIndex(nameIx);
  2445. output.WriteCodedIndex(CIx.TypeDefOrRef,eventType);
  2446. }
  2447. internal sealed override uint GetCodedIx(CIx code) {
  2448. switch (code) {
  2449. case (CIx.HasCustomAttr) : return 10;
  2450. case (CIx.HasSemantics) : return 0;
  2451. }
  2452. return 0;
  2453. }
  2454. }
  2455. /**************************************************************************/
  2456. /// <summary>
  2457. /// Descriptor for a class defined in another module of THIS assembly
  2458. /// and exported (.class extern)
  2459. /// </summary>
  2460. internal class ExternClass : Class
  2461. {
  2462. MetaDataElement parent;
  2463. uint flags;
  2464. internal ExternClass(TypeAttr attr, uint nsIx, uint nIx,
  2465. MetaDataElement paren) : base(nsIx,nIx) {
  2466. flags = (uint)attr;
  2467. parent = paren;
  2468. tabIx = MDTable.ExportedType;
  2469. }
  2470. internal sealed override uint Size(MetaData md) {
  2471. return 8 + 2* md.StringsIndexSize() + md.CodedIndexSize(CIx.Implementation);
  2472. }
  2473. internal sealed override void Write(FileImage output) {
  2474. output.Write(flags);
  2475. output.Write(0);
  2476. output.StringsIndex(nameIx);
  2477. output.StringsIndex(nameSpaceIx);
  2478. output.WriteCodedIndex(CIx.Implementation,parent);
  2479. }
  2480. internal sealed override uint GetCodedIx(CIx code) {
  2481. switch (code) {
  2482. case (CIx.HasCustomAttr) : return 17;
  2483. case (CIx.Implementation) : return 2;
  2484. }
  2485. return 0;
  2486. }
  2487. }
  2488. /**************************************************************************/
  2489. /// <summary>
  2490. /// Base class for Event and Property descriptors
  2491. /// </summary>
  2492. public class Feature : MetaDataElement
  2493. {
  2494. internal enum MethodType : ushort { Setter = 0x01, Getter, Other = 0x04, AddOn = 0x08,
  2495. RemoveOn = 0x10, Fire = 0x20 }
  2496. private static readonly int INITSIZE = 5;
  2497. private static readonly ushort specialName = 0x200;
  2498. private static readonly ushort rtSpecialName = 0x400;
  2499. protected ClassDef parent;
  2500. protected ushort flags = 0;
  2501. protected string name;
  2502. protected int tide = 0;
  2503. protected uint nameIx;
  2504. protected MethodSemantics[] methods = new MethodSemantics[INITSIZE];
  2505. internal Feature(string name, ClassDef par) {
  2506. parent = par;
  2507. this.name = name;
  2508. }
  2509. internal void AddMethod(MethodDef meth, MethodType mType) {
  2510. if (tide >= methods.Length) {
  2511. int len = methods.Length;
  2512. MethodSemantics[] mTmp = methods;
  2513. methods = new MethodSemantics[len * 2];
  2514. for (int i=0; i < len; i++) {
  2515. methods[i] = mTmp[i];
  2516. }
  2517. }
  2518. methods[tide++] = new MethodSemantics(mType,meth,this);
  2519. }
  2520. /// <summary>
  2521. /// Set the specialName attribute for this Event or Property
  2522. /// </summary>
  2523. public void SetSpecialName() {
  2524. flags |= specialName;
  2525. }
  2526. /// <summary>
  2527. /// Set the RTSpecialName attribute for this Event or Property
  2528. /// </summary>
  2529. public void SetRTSpecialName() {
  2530. flags |= rtSpecialName;
  2531. }
  2532. }
  2533. /*****************************************************************************/
  2534. /// <summary>
  2535. /// Descriptor for a field of a class
  2536. /// </summary>
  2537. public abstract class Field : Member
  2538. {
  2539. protected static readonly byte FieldSig = 0x6;
  2540. protected Type type;
  2541. internal Field(string pfName, Type pfType) : base(pfName)
  2542. {
  2543. type = pfType;
  2544. }
  2545. }
  2546. /**************************************************************************/
  2547. /// <summary>
  2548. /// Descriptor for a field defined in a class of THIS assembly/module
  2549. /// </summary>
  2550. public class FieldDef : Field
  2551. {
  2552. //private static readonly uint PInvokeImpl = 0x2000;
  2553. private static readonly ushort HasFieldMarshal = 0x1000;
  2554. private static readonly ushort HasFieldRVA = 0x100;
  2555. private static readonly ushort HasDefault = 0x8000;
  2556. FieldRVA rva;
  2557. ConstantElem constVal;
  2558. FieldLayout layout;
  2559. FieldMarshal marshalInfo;
  2560. ushort flags;
  2561. internal FieldDef(string name, Type fType) : base(name,fType) {
  2562. tabIx = MDTable.Field;
  2563. }
  2564. internal FieldDef(FieldAttr attrSet, string name, Type fType) : base(name, fType) {
  2565. flags = (ushort)attrSet;
  2566. tabIx = MDTable.Field;
  2567. }
  2568. /// <summary>
  2569. /// Add an attribute(s) to this field
  2570. /// </summary>
  2571. /// <param name="fa">the attribute(s) to be added</param>
  2572. public void AddFieldAttr(FieldAttr fa) {
  2573. flags |= (ushort)fa;
  2574. }
  2575. /// <summary>
  2576. /// Add a value for this field
  2577. /// </summary>
  2578. /// <param name="val">the value for the field</param>
  2579. public void AddValue(Constant val) {
  2580. constVal = new ConstantElem(this,val);
  2581. flags |= HasDefault;
  2582. }
  2583. /// <summary>
  2584. /// Add an initial value for this field (at dataLabel) (.data)
  2585. /// </summary>
  2586. /// <param name="val">the value for the field</param>
  2587. /// <param name="repeatVal">the number of repetitions of this value</param>
  2588. public void AddDataValue(DataConstant val) {
  2589. flags |= HasFieldRVA;
  2590. rva = new FieldRVA(this,val);
  2591. }
  2592. /// <summary>
  2593. /// Set the offset of the field. Used for sequential or explicit classes.
  2594. /// (.field [offs])
  2595. /// </summary>
  2596. /// <param name="offs">field offset</param>
  2597. public void SetOffset(uint offs) {
  2598. layout = new FieldLayout(this,offs);
  2599. }
  2600. /// <summary>
  2601. /// Set the marshalling info for a field
  2602. /// </summary>
  2603. /// <param name="mInf"></param>
  2604. public void SetMarshalInfo(NativeType marshallType) {
  2605. flags |= HasFieldMarshal;
  2606. marshalInfo = new FieldMarshal(this,marshallType);
  2607. }
  2608. internal sealed override void BuildTables(MetaData md) {
  2609. if (done) return;
  2610. nameIx = md.AddToStringsHeap(name);
  2611. MemoryStream sig = new MemoryStream();
  2612. sig.WriteByte(FieldSig);
  2613. type.TypeSig(sig);
  2614. sigIx = md.AddToBlobHeap(sig.ToArray());
  2615. if (rva != null) {
  2616. md.AddToTable(MDTable.FieldRVA,rva);
  2617. rva.BuildTables(md);
  2618. } else if (constVal != null) {
  2619. md.AddToTable(MDTable.Constant,constVal);
  2620. constVal.BuildTables(md);
  2621. }
  2622. if (layout != null) md.AddToTable(MDTable.FieldLayout,layout);
  2623. if (marshalInfo != null) {
  2624. md.AddToTable(MDTable.FieldMarshal,marshalInfo);
  2625. marshalInfo.BuildTables(md);
  2626. }
  2627. done = true;
  2628. }
  2629. internal sealed override uint Size(MetaData md) {
  2630. return 2 + md.StringsIndexSize() + md.BlobIndexSize();
  2631. }
  2632. internal sealed override void Write(FileImage output) {
  2633. output.Write(flags);
  2634. output.StringsIndex(nameIx);
  2635. output.BlobIndex(sigIx);
  2636. }
  2637. internal sealed override uint GetCodedIx(CIx code) {
  2638. switch (code) {
  2639. case (CIx.HasConst) : return 0;
  2640. case (CIx.HasCustomAttr) : return 1;
  2641. case (CIx.HasFieldMarshal) : return 0;
  2642. case (CIx.MemberForwarded) : return 0;
  2643. }
  2644. return 0;
  2645. }
  2646. }
  2647. /**************************************************************************/
  2648. /// <summary>
  2649. /// Descriptor for layout information for a field
  2650. /// </summary>
  2651. public class FieldLayout : MetaDataElement
  2652. {
  2653. Field field;
  2654. uint offset;
  2655. internal FieldLayout(Field field, uint offset) {
  2656. this.field = field;
  2657. this.offset = offset;
  2658. tabIx = MDTable.FieldLayout;
  2659. }
  2660. internal sealed override uint Size(MetaData md) {
  2661. return 4 + md.TableIndexSize(MDTable.Field);
  2662. }
  2663. internal sealed override void Write(FileImage output) {
  2664. output.Write(offset);
  2665. output.WriteIndex(MDTable.Field,field.Row);
  2666. }
  2667. }
  2668. /*****************************************************************************/
  2669. /// <summary>
  2670. /// Marshalling information for a field or param
  2671. /// </summary>
  2672. public class FieldMarshal : MetaDataElement
  2673. {
  2674. MetaDataElement field;
  2675. NativeType nt;
  2676. uint ntIx;
  2677. internal FieldMarshal(MetaDataElement field, NativeType nType) {
  2678. this.field = field;
  2679. this.nt = nType;
  2680. tabIx = MDTable.FieldMarshal;
  2681. }
  2682. internal sealed override void BuildTables(MetaData md) {
  2683. if (done) return;
  2684. ntIx = md.AddToBlobHeap(nt.ToBlob());
  2685. done = true;
  2686. }
  2687. internal sealed override uint Size(MetaData md) {
  2688. return md.CodedIndexSize(CIx.HasFieldMarshal) + md.BlobIndexSize();
  2689. }
  2690. internal sealed override void Write(FileImage output) {
  2691. output.WriteCodedIndex(CIx.HasFieldMarshal,field);
  2692. output.BlobIndex(ntIx);
  2693. }
  2694. }
  2695. /**************************************************************************/
  2696. /// <summary>
  2697. /// Descriptor for a field of a class defined in another assembly/module
  2698. /// </summary>
  2699. public class FieldRef : Field
  2700. {
  2701. MetaDataElement parent;
  2702. internal FieldRef(MetaDataElement paren, string name, Type fType) : base(name, fType) {
  2703. parent = paren;
  2704. }
  2705. internal sealed override void BuildTables(MetaData md) {
  2706. if (done) return;
  2707. nameIx = md.AddToStringsHeap(name);
  2708. MemoryStream sig = new MemoryStream();
  2709. sig.WriteByte(FieldSig);
  2710. type.TypeSig(sig);
  2711. sigIx = md.AddToBlobHeap(sig.ToArray());
  2712. done = true;
  2713. }
  2714. internal sealed override uint Size(MetaData md) {
  2715. return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
  2716. }
  2717. internal sealed override void Write(FileImage output) {
  2718. output.WriteCodedIndex(CIx.MemberRefParent,parent);
  2719. output.StringsIndex(nameIx);
  2720. output.BlobIndex(sigIx);
  2721. }
  2722. internal sealed override uint GetCodedIx(CIx code) { return 6; }
  2723. }
  2724. /**************************************************************************/
  2725. /// <summary>
  2726. /// Descriptor for the address of a field's value in the PE file
  2727. /// </summary>
  2728. public class FieldRVA : MetaDataElement
  2729. {
  2730. Field field;
  2731. DataConstant data;
  2732. internal FieldRVA(Field field, DataConstant data) {
  2733. this.field = field;
  2734. this.data = data;
  2735. tabIx = MDTable.FieldRVA;
  2736. }
  2737. internal sealed override void BuildTables(MetaData md) {
  2738. if (done) return;
  2739. md.AddData(data);
  2740. done = true;
  2741. }
  2742. internal sealed override uint Size(MetaData md) {
  2743. return 4 + md.TableIndexSize(MDTable.Field);
  2744. }
  2745. internal sealed override void Write(FileImage output) {
  2746. output.WriteDataRVA(data.DataOffset);
  2747. output.WriteIndex(MDTable.Field,field.Row);
  2748. }
  2749. }
  2750. /**************************************************************************/
  2751. /// <summary>
  2752. /// Image for a PEFile
  2753. /// File Structure
  2754. /// DOS Header (128 bytes)
  2755. /// PE Signature ("PE\0\0")
  2756. /// PEFileHeader (20 bytes)
  2757. /// PEOptionalHeader (224 bytes)
  2758. /// SectionHeaders (40 bytes * NumSections)
  2759. ///
  2760. /// Sections .text (always present - contains metadata)
  2761. /// .sdata (contains any initialised data in the file - may not be present)
  2762. /// (for ilams /debug this contains the Debug table)
  2763. /// .reloc (always present - in pure CIL only has one fixup)
  2764. /// others??? c# produces .rsrc section containing a Resource Table
  2765. ///
  2766. /// .text layout
  2767. /// IAT (single entry 8 bytes for pure CIL)
  2768. /// CLIHeader (72 bytes)
  2769. /// CIL instructions for all methods (variable size)
  2770. /// MetaData
  2771. /// Root (20 bytes + UTF-8 Version String + quad align padding)
  2772. /// StreamHeaders (8 bytes + null terminated name string + quad align padding)
  2773. /// Streams
  2774. /// #~ (always present - holds metadata tables)
  2775. /// #Strings (always present - holds identifier strings)
  2776. /// #US (Userstring heap)
  2777. /// #Blob (signature blobs)
  2778. /// #GUID (guids for assemblies or Modules)
  2779. /// ImportTable (40 bytes)
  2780. /// ImportLookupTable(8 bytes) (same as IAT for standard CIL files)
  2781. /// Hint/Name Tables with entry "_CorExeMain" for .exe file and "_CorDllMain" for .dll (14 bytes)
  2782. /// ASCII string "mscoree.dll" referenced in ImportTable (+ padding = 16 bytes)
  2783. /// Entry Point (0xFF25 followed by 4 bytes 0x400000 + RVA of .text)
  2784. ///
  2785. /// #~ stream structure
  2786. /// Header (24 bytes)
  2787. /// Rows (4 bytes * numTables)
  2788. /// Tables
  2789. /// </summary>
  2790. internal class FileImage : BinaryWriter
  2791. {
  2792. internal readonly static uint[] iByteMask = {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000};
  2793. internal readonly static ulong[] lByteMask = {0x00000000000000FF, 0x000000000000FF00,
  2794. 0x0000000000FF0000, 0x00000000FF000000,
  2795. 0x000000FF00000000, 0x0000FF0000000000,
  2796. 0x00FF000000000000, 0xFF00000000000000 };
  2797. internal readonly static uint nibble0Mask = 0x0000000F;
  2798. internal readonly static uint nibble1Mask = 0x000000F0;
  2799. private static readonly byte[] DOSHeader = { 0x4d,0x5a,0x90,0x00,0x03,0x00,0x00,0x00,
  2800. 0x04,0x00,0x00,0x00,0xff,0xff,0x00,0x00,
  2801. 0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2802. 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2803. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2804. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2805. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2806. 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,
  2807. 0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,
  2808. 0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68,
  2809. 0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,
  2810. 0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f,
  2811. 0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,
  2812. 0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20,
  2813. 0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,
  2814. 0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2815. 0x50,0x45,0x00,0x00};
  2816. private static byte[] PEHeader = { 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2817. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2818. 0xE0, 0x00, 0x0E, 0x01, // PE Header Standard Fields
  2819. 0x0B, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
  2820. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2821. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  2822. };
  2823. private static readonly uint minFileAlign = 0x200;
  2824. private static readonly uint maxFileAlign = 0x1000;
  2825. private static readonly uint fileHeaderSize = 0x178;
  2826. private static readonly uint sectionHeaderSize = 40;
  2827. private static readonly uint SectionAlignment = 0x2000;
  2828. private static readonly uint ImageBase = 0x400000;
  2829. private static readonly uint ImportTableSize = 40;
  2830. private static readonly uint IATSize = 8;
  2831. private static readonly uint CLIHeaderSize = 72;
  2832. private uint runtimeFlags = 0x01; // COMIMAGE_FLAGS_ILONLY
  2833. // 32BITREQUIRED 0x02, STRONGNAMESIGNED 0x08, TRACKDEBUGDATA 0x10000
  2834. private static readonly uint StrongNameSignatureSize = 128;
  2835. private bool reserveStrongNameSignatureSpace = false;
  2836. private static readonly uint relocFlags = 0x42000040;
  2837. private static readonly ushort exeCharacteristics = 0x010E;
  2838. private static readonly ushort dllCharacteristics = 0x210E;
  2839. // section names are all 8 bytes
  2840. private static readonly string textName = ".text\0\0\0";
  2841. private static readonly string sdataName = ".sdata\0\0";
  2842. private static readonly string relocName = ".reloc\0\0";
  2843. private static readonly string rsrcName = ".rsrc\0\0\0";
  2844. private static readonly string exeHintNameTable = "\0\0_CorExeMain\0";
  2845. private static readonly string dllHintNameTable = "\0\0_CorDllMain\0";
  2846. private static readonly string runtimeEngineName = "mscoree.dll\0\0";
  2847. private Section text, sdata, rsrc;
  2848. ArrayList data;
  2849. BinaryWriter reloc = new BinaryWriter(new MemoryStream());
  2850. uint dateStamp = 0;
  2851. DateTime origin = new DateTime(1970,1,1);
  2852. uint numSections = 2; // always have .text and .reloc sections
  2853. internal SubSystem subSys = SubSystem.Windows_CUI; // default is Windows Console mode
  2854. internal uint fileAlign = minFileAlign;
  2855. uint entryPointOffset, entryPointPadding, imageSize, headerSize, headerPadding, entryPointToken = 0;
  2856. uint relocOffset, relocRVA, relocSize, relocPadding, relocTide, hintNameTableOffset;
  2857. uint metaDataOffset, runtimeEngineOffset, initDataSize = 0, importTablePadding;
  2858. uint strongNameSigOffset;
  2859. uint importTableOffset, importLookupTableOffset, totalImportTableSize;
  2860. MetaData metaData;
  2861. char[] runtimeEngine = runtimeEngineName.ToCharArray(), hintNameTable;
  2862. bool doDLL, largeStrings, largeGUID, largeUS, largeBlob;
  2863. ushort characteristics;
  2864. internal FileImage(bool makeDLL, string fileName) : base(new FileStream(fileName,FileMode.Create)) {
  2865. InitFileImage(makeDLL);
  2866. TimeSpan tmp = System.IO.File.GetCreationTime(fileName).Subtract(origin);
  2867. dateStamp = Convert.ToUInt32(tmp.TotalSeconds);
  2868. }
  2869. internal FileImage(bool makeDLL, Stream str) : base(str) {
  2870. InitFileImage(makeDLL);
  2871. TimeSpan tmp = DateTime.Now.Subtract(origin);
  2872. dateStamp = Convert.ToUInt32(tmp.TotalSeconds);
  2873. }
  2874. private void InitFileImage(bool makeDLL) {
  2875. doDLL = makeDLL;
  2876. if (doDLL) {
  2877. hintNameTable = dllHintNameTable.ToCharArray();
  2878. characteristics = dllCharacteristics;
  2879. } else {
  2880. hintNameTable = exeHintNameTable.ToCharArray();
  2881. characteristics = exeCharacteristics;
  2882. }
  2883. text = new Section(textName,0x60000020); // IMAGE_SCN_CNT CODE, EXECUTE, READ
  2884. // rsrc = new Section(rsrcName,0x40000040); // IMAGE_SCN_CNT INITIALIZED_DATA, READ
  2885. metaData = new MetaData(this);
  2886. }
  2887. internal MetaData GetMetaData() {
  2888. return metaData;
  2889. }
  2890. private uint GetNextSectStart(uint rva, uint tide) {
  2891. if (tide < SectionAlignment) return rva + SectionAlignment;
  2892. return rva + ((tide / SectionAlignment) + 1) * SectionAlignment;
  2893. }
  2894. private void BuildTextSection() {
  2895. // .text layout
  2896. // IAT (single entry 8 bytes for pure CIL)
  2897. // CLIHeader (72 bytes)
  2898. // CIL instructions for all methods (variable size)
  2899. // MetaData
  2900. // ImportTable (40 bytes)
  2901. // ImportLookupTable(8 bytes) (same as IAT for standard CIL files)
  2902. // Hint/Name Tables with entry "_CorExeMain" for .exe file and "_CorDllMain" for .dll (14 bytes)
  2903. // ASCII string "mscoree.dll" referenced in ImportTable (+ padding = 16 bytes)
  2904. // Entry Point (0xFF25 followed by 4 bytes 0x400000 + RVA of .text)
  2905. metaData.BuildMetaData(IATSize + CLIHeaderSize);
  2906. metaDataOffset = IATSize + CLIHeaderSize;
  2907. // Console.WriteLine("Code starts at " + metaDataOffset);
  2908. metaDataOffset += metaData.CodeSize();
  2909. // resourcesStart =
  2910. if (reserveStrongNameSignatureSpace) {
  2911. strongNameSigOffset = metaDataOffset + metaData.Size();
  2912. // fixUps = RVA for vtable
  2913. importTableOffset = strongNameSigOffset + StrongNameSignatureSize;
  2914. } else {
  2915. strongNameSigOffset = 0;
  2916. // fixUps = RVA for vtable
  2917. importTableOffset = metaDataOffset + metaData.Size();
  2918. }
  2919. importTablePadding = NumToAlign(importTableOffset,16);
  2920. importTableOffset += importTablePadding;
  2921. importLookupTableOffset = importTableOffset + ImportTableSize;
  2922. hintNameTableOffset = importLookupTableOffset + IATSize;
  2923. runtimeEngineOffset = hintNameTableOffset + (uint)hintNameTable.Length;
  2924. entryPointOffset = runtimeEngineOffset + (uint)runtimeEngine.Length;
  2925. totalImportTableSize = entryPointOffset - importTableOffset;
  2926. // Console.WriteLine("total import table size = " + totalImportTableSize);
  2927. // Console.WriteLine("entrypoint offset = " + entryPointOffset);
  2928. entryPointPadding = NumToAlign(entryPointOffset,4) + 2;
  2929. entryPointOffset += entryPointPadding;
  2930. text.AddReloc(entryPointOffset+2);
  2931. text.IncTide(entryPointOffset + 6);
  2932. //if (text.Tide() < fileAlign) fileAlign = minFileAlign;
  2933. text.SetSize(NumToAlign(text.Tide(),fileAlign));
  2934. // Console.WriteLine("text size = " + text.Size() + " text tide = " + text.Tide() + " text padding = " + text.Padding());
  2935. // Console.WriteLine("metaDataOffset = " + Hex.Int(metaDataOffset));
  2936. // Console.WriteLine("importTableOffset = " + Hex.Int(importTableOffset));
  2937. // Console.WriteLine("importLookupTableOffset = " + Hex.Int(importLookupTableOffset));
  2938. // Console.WriteLine("hintNameTableOffset = " + Hex.Int(hintNameTableOffset));
  2939. // Console.WriteLine("runtimeEngineOffset = " + Hex.Int(runtimeEngineOffset));
  2940. // Console.WriteLine("entryPointOffset = " + Hex.Int(entryPointOffset));
  2941. // Console.WriteLine("entryPointPadding = " + Hex.Int(entryPointPadding));
  2942. }
  2943. internal void BuildRelocSection() {
  2944. text.DoRelocs(reloc);
  2945. if (sdata != null) sdata.DoRelocs(reloc);
  2946. if (rsrc != null) rsrc.DoRelocs(reloc);
  2947. relocTide = (uint)reloc.Seek(0,SeekOrigin.Current);
  2948. relocPadding = NumToAlign(relocTide,fileAlign);
  2949. relocSize = relocTide + relocPadding;
  2950. imageSize = relocRVA + SectionAlignment;
  2951. initDataSize += relocSize;
  2952. }
  2953. private void CalcOffsets() {
  2954. if (sdata != null)
  2955. numSections++;
  2956. if (rsrc != null)
  2957. numSections++;
  2958. headerSize = fileHeaderSize + (numSections * sectionHeaderSize);
  2959. headerPadding = NumToAlign(headerSize,fileAlign);
  2960. headerSize += headerPadding;
  2961. uint offset = headerSize;
  2962. uint rva = SectionAlignment;
  2963. text.SetOffset(offset);
  2964. text.SetRVA(rva);
  2965. offset += text.Size();
  2966. rva = GetNextSectStart(rva,text.Tide());
  2967. // Console.WriteLine("headerSize = " + headerSize);
  2968. // Console.WriteLine("headerPadding = " + headerPadding);
  2969. // Console.WriteLine("textOffset = " + Hex.Int(text.Offset()));
  2970. if (sdata != null) {
  2971. sdata.SetSize(NumToAlign(sdata.Tide(),fileAlign));
  2972. sdata.SetOffset(offset);
  2973. sdata.SetRVA(rva);
  2974. offset += sdata.Size();
  2975. rva = GetNextSectStart(rva,sdata.Tide());
  2976. initDataSize += sdata.Size();
  2977. }
  2978. if (rsrc != null) {
  2979. rsrc.SetSize(NumToAlign(rsrc.Tide(),fileAlign));
  2980. rsrc.SetOffset(offset);
  2981. rsrc.SetRVA(rva);
  2982. offset += rsrc.Size();
  2983. rva = GetNextSectStart(rva,rsrc.Tide());
  2984. initDataSize += rsrc.Size();
  2985. }
  2986. relocOffset = offset;
  2987. relocRVA = rva;
  2988. }
  2989. internal void MakeFile() {
  2990. if (doDLL) hintNameTable = dllHintNameTable.ToCharArray();
  2991. else hintNameTable = exeHintNameTable.ToCharArray();
  2992. BuildTextSection();
  2993. CalcOffsets();
  2994. BuildRelocSection();
  2995. // now write it out
  2996. WriteHeader();
  2997. WriteSections();
  2998. Flush();
  2999. Close();
  3000. }
  3001. private void WriteHeader() {
  3002. Write(DOSHeader);
  3003. // Console.WriteLine("Writing PEHeader at offset " + Seek(0,SeekOrigin.Current));
  3004. WritePEHeader();
  3005. // Console.WriteLine("Writing text section header at offset " + Hex.Long(Seek(0,SeekOrigin.Current)));
  3006. text.WriteHeader(this,relocRVA);
  3007. if (sdata != null) sdata.WriteHeader(this,relocRVA);
  3008. if (rsrc != null) rsrc.WriteHeader(this,relocRVA);
  3009. // Console.WriteLine("Writing reloc section header at offset " + Seek(0,SeekOrigin.Current));
  3010. WriteRelocSectionHeader();
  3011. // Console.WriteLine("Writing padding at offset " + Seek(0,SeekOrigin.Current));
  3012. WriteZeros(headerPadding);
  3013. }
  3014. private void WriteSections() {
  3015. // Console.WriteLine("Writing text section at offset " + Seek(0,SeekOrigin.Current));
  3016. WriteTextSection();
  3017. if (sdata != null) WriteSDataSection();
  3018. if (rsrc != null) WriteRsrcSection();
  3019. WriteRelocSection();
  3020. }
  3021. private void WriteIAT() {
  3022. Write(text.RVA() + hintNameTableOffset);
  3023. Write(0);
  3024. }
  3025. private void WriteImportTables() {
  3026. // Import Table
  3027. WriteZeros(importTablePadding);
  3028. // Console.WriteLine("Writing import tables at offset " + Hex.Long(Seek(0,SeekOrigin.Current)));
  3029. Write(importLookupTableOffset + text.RVA());
  3030. WriteZeros(8);
  3031. Write(runtimeEngineOffset + text.RVA());
  3032. Write(text.RVA()); // IAT is at the beginning of the text section
  3033. WriteZeros(20);
  3034. // Import Lookup Table
  3035. WriteIAT(); // lookup table and IAT are the same
  3036. // Hint/Name Table
  3037. // Console.WriteLine("Writing hintname table at " + Hex.Long(Seek(0,SeekOrigin.Current)));
  3038. Write(hintNameTable);
  3039. Write(runtimeEngineName.ToCharArray());
  3040. }
  3041. private void WriteTextSection() {
  3042. WriteIAT();
  3043. WriteCLIHeader();
  3044. // Console.WriteLine("Writing code at " + Hex.Long(Seek(0,SeekOrigin.Current)));
  3045. metaData.WriteByteCodes(this);
  3046. // Console.WriteLine("Finished writing code at " + Hex.Long(Seek(0,SeekOrigin.Current)));
  3047. largeStrings = metaData.LargeStringsIndex();
  3048. largeGUID = metaData.LargeGUIDIndex();
  3049. largeUS = metaData.LargeUSIndex();
  3050. largeBlob = metaData.LargeBlobIndex();
  3051. metaData.WriteMetaData(this);
  3052. if (reserveStrongNameSignatureSpace) {
  3053. WriteZeros(StrongNameSignatureSize);
  3054. }
  3055. WriteImportTables();
  3056. WriteZeros(entryPointPadding);
  3057. Write((ushort)0x25FF);
  3058. Write(ImageBase + text.RVA());
  3059. WriteZeros(text.Padding());
  3060. }
  3061. private void WriteCLIHeader() {
  3062. Write(CLIHeaderSize); // Cb
  3063. Write((short)2); // Major runtime version
  3064. Write((short)0); // Minor runtime version
  3065. Write(text.RVA() + metaDataOffset);
  3066. Write(metaData.Size());
  3067. Write(runtimeFlags);
  3068. Write(entryPointToken);
  3069. WriteZeros(8); // Resources - used by Manifest Resources NYI
  3070. // Strong Name Signature (RVA, size)
  3071. if (reserveStrongNameSignatureSpace) {
  3072. Write(text.RVA() + strongNameSigOffset);
  3073. Write(StrongNameSignatureSize);
  3074. } else {
  3075. WriteZeros(8);
  3076. }
  3077. WriteZeros(8); // CodeManagerTable
  3078. WriteZeros(8); // VTableFixups NYI
  3079. WriteZeros(16); // ExportAddressTableJumps, ManagedNativeHeader
  3080. }
  3081. private void WriteSDataSection() {
  3082. long size = sdata.Size ();
  3083. long start = BaseStream.Position;
  3084. for (int i=0; i < data.Count; i++) {
  3085. ((DataConstant)data[i]).Write(this);
  3086. }
  3087. while (BaseStream.Position < (start + size))
  3088. Write ((byte) 0);
  3089. }
  3090. private void WriteRsrcSection() {
  3091. }
  3092. private void WriteRelocSection() {
  3093. // Console.WriteLine("Writing reloc section at " + Seek(0,SeekOrigin.Current) + " = " + relocOffset);
  3094. MemoryStream str = (MemoryStream)reloc.BaseStream;
  3095. Write(str.ToArray());
  3096. WriteZeros(NumToAlign((uint)str.Position,fileAlign));
  3097. }
  3098. internal void SetEntryPoint(uint entryPoint) {
  3099. entryPointToken = entryPoint;
  3100. }
  3101. internal void AddInitData(DataConstant cVal) {
  3102. if (sdata == null) {
  3103. sdata = new Section(sdataName,0xC0000040); // IMAGE_SCN_CNT INITIALIZED_DATA, READ, WRITE
  3104. data = new ArrayList();
  3105. }
  3106. data.Add(cVal);
  3107. cVal.DataOffset = sdata.Tide();
  3108. sdata.IncTide(cVal.GetSize());
  3109. }
  3110. internal void WriteZeros(uint numZeros) {
  3111. for (int i=0; i < numZeros; i++) {
  3112. Write((byte)0);
  3113. }
  3114. }
  3115. internal void WritePEHeader() {
  3116. Write((ushort)0x014C); // Machine - always 0x14C for Managed PE Files (allow others??)
  3117. Write((ushort)numSections);
  3118. Write(dateStamp);
  3119. WriteZeros(8); // Pointer to Symbol Table and Number of Symbols (always zero for ECMA CLI files)
  3120. Write((ushort)0x00E0); // Size of Optional Header
  3121. Write(characteristics);
  3122. // PE Optional Header
  3123. Write((ushort)0x010B); // Magic
  3124. Write((byte)0x6); // LMajor pure-IL = 6 C++ = 7
  3125. Write((byte)0x0); // LMinor
  3126. Write(text.Size());
  3127. Write(initDataSize);
  3128. Write(0); // Check other sections here!!
  3129. Write(text.RVA() + entryPointOffset);
  3130. Write(text.RVA());
  3131. uint dataBase = 0;
  3132. if (sdata != null) dataBase = sdata.RVA();
  3133. else if (rsrc != null) dataBase = rsrc.RVA();
  3134. else dataBase = relocRVA;
  3135. Write(dataBase);
  3136. Write(ImageBase);
  3137. Write(SectionAlignment);
  3138. Write(fileAlign);
  3139. Write((ushort)0x04); // OS Major
  3140. WriteZeros(6); // OS Minor, User Major, User Minor
  3141. Write((ushort)0x04); // SubSys Major
  3142. WriteZeros(6); // SybSys Minor, Reserved
  3143. Write(imageSize);
  3144. Write(headerSize);
  3145. Write((int)0); // File Checksum
  3146. Write((ushort)subSys);
  3147. Write((short)0); // DLL Flags
  3148. Write((uint)0x100000); // Stack Reserve Size
  3149. Write((uint)0x1000); // Stack Commit Size
  3150. Write((uint)0x100000); // Heap Reserve Size
  3151. Write((uint)0x1000); // Heap Commit Size
  3152. Write(0); // Loader Flags
  3153. Write(0x10); // Number of Data Directories
  3154. WriteZeros(8); // Export Table
  3155. Write(importTableOffset + text.RVA());
  3156. Write(totalImportTableSize);
  3157. WriteZeros(24); // Resource, Exception and Certificate Tables
  3158. Write(relocRVA);
  3159. Write(relocTide);
  3160. WriteZeros(48); // Debug, Copyright, Global Ptr, TLS, Load Config and Bound Import Tables
  3161. Write(text.RVA()); // IATRVA - IAT is at start of .text Section
  3162. Write(IATSize);
  3163. WriteZeros(8); // Delay Import Descriptor
  3164. Write(text.RVA()+IATSize); // CLIHeader immediately follows IAT
  3165. Write(CLIHeaderSize);
  3166. WriteZeros(8); // Reserved
  3167. }
  3168. internal void WriteRelocSectionHeader() {
  3169. Write(relocName.ToCharArray());
  3170. Write(relocTide);
  3171. Write(relocRVA);
  3172. Write(relocSize);
  3173. Write(relocOffset);
  3174. WriteZeros(12);
  3175. Write(relocFlags);
  3176. }
  3177. private void Align (MemoryStream str, int val) {
  3178. if ((str.Position % val) != 0) {
  3179. for (int i=val - (int)(str.Position % val); i > 0; i--) {
  3180. str.WriteByte(0);
  3181. }
  3182. }
  3183. }
  3184. private uint Align(uint val, uint alignVal) {
  3185. if ((val % alignVal) != 0) {
  3186. val += alignVal - (val % alignVal);
  3187. }
  3188. return val;
  3189. }
  3190. private uint NumToAlign(uint val, uint alignVal) {
  3191. if ((val % alignVal) == 0) return 0;
  3192. return alignVal - (val % alignVal);
  3193. }
  3194. internal void StringsIndex(uint ix) {
  3195. if (largeStrings) Write(ix);
  3196. else Write((ushort)ix);
  3197. }
  3198. internal void GUIDIndex(uint ix) {
  3199. if (largeGUID) Write(ix);
  3200. else Write((ushort)ix);
  3201. }
  3202. internal void USIndex(uint ix) {
  3203. if (largeUS) Write(ix);
  3204. else Write((ushort)ix);
  3205. }
  3206. internal void BlobIndex(uint ix) {
  3207. if (largeBlob) Write(ix);
  3208. else Write((ushort)ix);
  3209. }
  3210. internal void WriteIndex(MDTable tabIx,uint ix) {
  3211. if (metaData.LargeIx(tabIx)) Write(ix);
  3212. else Write((ushort)ix);
  3213. }
  3214. internal void WriteCodedIndex(CIx code, MetaDataElement elem) {
  3215. metaData.WriteCodedIndex(code,elem,this);
  3216. }
  3217. internal void WriteCodeRVA(uint offs) {
  3218. Write(text.RVA() + offs);
  3219. }
  3220. internal void WriteDataRVA(uint offs) {
  3221. Write(sdata.RVA() + offs);
  3222. }
  3223. internal void Write3Bytes(uint val) {
  3224. byte b3 = (byte)((val & FileImage.iByteMask[2]) >> 16);
  3225. byte b2 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
  3226. byte b1 = (byte)(val & FileImage.iByteMask[0]);
  3227. Write(b1);
  3228. Write(b2);
  3229. Write(b3);
  3230. }
  3231. internal bool ReserveStrongNameSignatureSpace {
  3232. get { return reserveStrongNameSignatureSpace; }
  3233. set { reserveStrongNameSignatureSpace = value; }
  3234. }
  3235. }
  3236. /**************************************************************************/
  3237. /// <summary>
  3238. /// Descriptor for a file referenced in THIS assembly/module (.file)
  3239. /// </summary>
  3240. public class FileRef : MetaDataElement
  3241. {
  3242. private static readonly uint NoMetaData = 0x1;
  3243. uint nameIx = 0, hashIx = 0;
  3244. uint flags = 0;
  3245. internal FileRef(string name, byte[] hashBytes, bool metaData,
  3246. bool entryPoint, MetaData md) {
  3247. if (!metaData) flags = NoMetaData;
  3248. if (entryPoint) md.SetEntryPoint(this);
  3249. nameIx = md.AddToStringsHeap(name);
  3250. hashIx = md.AddToBlobHeap(hashBytes);
  3251. tabIx = MDTable.File;
  3252. }
  3253. internal FileRef(uint nameIx, byte[] hashBytes, bool metaData,
  3254. bool entryPoint, MetaData md) {
  3255. if (!metaData) flags = NoMetaData;
  3256. if (entryPoint) md.SetEntryPoint(this);
  3257. this.nameIx = nameIx;
  3258. hashIx = md.AddToBlobHeap(hashBytes);
  3259. tabIx = MDTable.File;
  3260. }
  3261. internal sealed override uint Size(MetaData md) {
  3262. return 4 + md.StringsIndexSize() + md.BlobIndexSize();
  3263. }
  3264. internal sealed override void Write(FileImage output) {
  3265. output.Write(flags);
  3266. output.StringsIndex(nameIx);
  3267. output.BlobIndex(hashIx);
  3268. }
  3269. internal sealed override uint GetCodedIx(CIx code) {
  3270. switch (code) {
  3271. case (CIx.HasCustomAttr) : return 16;
  3272. case (CIx.Implementation) : return 0;
  3273. }
  3274. return 0;
  3275. }
  3276. }
  3277. /**************************************************************************/
  3278. /// <summary>
  3279. /// Descriptor for pinvoke information for a method NOT YET IMPLEMENTED
  3280. /// </summary>
  3281. public class ImplMap : MetaDataElement
  3282. {
  3283. private static readonly ushort NoMangle = 0x01;
  3284. ushort flags;
  3285. Method meth;
  3286. string importName;
  3287. uint iNameIx;
  3288. ModuleRef importScope;
  3289. internal ImplMap(ushort flag, Method implMeth, string iName, ModuleRef mScope) {
  3290. flags = flag;
  3291. meth = implMeth;
  3292. importName = iName;
  3293. importScope = mScope;
  3294. tabIx = MDTable.ImplMap;
  3295. if (iName == null) flags |= NoMangle;
  3296. //throw(new NotYetImplementedException("PInvoke "));
  3297. }
  3298. internal sealed override void BuildTables(MetaData md) {
  3299. if (done) return;
  3300. iNameIx = md.AddToStringsHeap(importName);
  3301. done = true;
  3302. }
  3303. internal sealed override uint Size(MetaData md) {
  3304. return 2+ md.CodedIndexSize(CIx.MemberForwarded) +
  3305. md.StringsIndexSize() + md.TableIndexSize(MDTable.ModuleRef);
  3306. }
  3307. internal sealed override void Write(FileImage output) {
  3308. output.Write(flags);
  3309. output.WriteCodedIndex(CIx.MemberForwarded,meth);
  3310. output.StringsIndex(iNameIx);
  3311. output.WriteIndex(MDTable.ModuleRef,importScope.Row);
  3312. }
  3313. }
  3314. /**************************************************************************/
  3315. /// <summary>
  3316. /// Descriptor for an IL instruction
  3317. /// </summary>
  3318. internal abstract class CILInstruction {
  3319. protected static readonly sbyte maxByteVal = 127;
  3320. protected static readonly sbyte minByteVal = -128;
  3321. protected static readonly byte leadByte = 0xFE;
  3322. protected static readonly uint USHeapIndex = 0x70000000;
  3323. protected static readonly int longInstrStart = (int)Op.arglist;
  3324. public bool twoByteInstr = false;
  3325. public uint size = 0;
  3326. public uint offset;
  3327. internal virtual bool Check(MetaData md) {
  3328. return false;
  3329. }
  3330. internal virtual void Write(FileImage output) { }
  3331. }
  3332. internal class CILByte : CILInstruction {
  3333. byte byteVal;
  3334. internal CILByte(byte bVal) {
  3335. byteVal = bVal;
  3336. size = 1;
  3337. }
  3338. internal override void Write(FileImage output) {
  3339. output.Write(byteVal);
  3340. }
  3341. }
  3342. internal class Instr : CILInstruction {
  3343. protected int instr;
  3344. internal Instr(int inst) {
  3345. if (inst >= longInstrStart) {
  3346. instr = inst - longInstrStart;
  3347. twoByteInstr = true;
  3348. size = 2;
  3349. } else {
  3350. instr = inst;
  3351. size = 1;
  3352. }
  3353. }
  3354. internal override void Write(FileImage output) {
  3355. //Console.WriteLine("Writing instruction " + instr + " with size " + size);
  3356. if (twoByteInstr) output.Write(leadByte);
  3357. output.Write((byte)instr);
  3358. }
  3359. }
  3360. internal class IntInstr : Instr {
  3361. int val;
  3362. bool byteNum;
  3363. internal IntInstr(int inst, int num, bool byteSize) : base(inst) {
  3364. val = num;
  3365. byteNum = byteSize;
  3366. if (byteNum) size++;
  3367. else size += 4;
  3368. }
  3369. internal sealed override void Write(FileImage output) {
  3370. base.Write(output);
  3371. if (byteNum)
  3372. output.Write((sbyte)val);
  3373. else
  3374. output.Write(val);
  3375. }
  3376. }
  3377. internal class UIntInstr : Instr {
  3378. int val;
  3379. bool byteNum;
  3380. internal UIntInstr(int inst, int num, bool byteSize) : base(inst) {
  3381. val = num;
  3382. byteNum = byteSize;
  3383. if (byteNum) size++;
  3384. else size += 2;
  3385. }
  3386. internal sealed override void Write(FileImage output) {
  3387. base.Write(output);
  3388. if (byteNum)
  3389. output.Write((byte)val);
  3390. else
  3391. output.Write((ushort)val);
  3392. }
  3393. }
  3394. internal class LongInstr : Instr {
  3395. long val;
  3396. internal LongInstr(int inst, long l) : base(inst) {
  3397. val = l;
  3398. size += 8;
  3399. }
  3400. internal sealed override void Write(FileImage output) {
  3401. base.Write(output);
  3402. output.Write(val);
  3403. }
  3404. }
  3405. internal class FloatInstr : Instr {
  3406. float fVal;
  3407. internal FloatInstr(int inst, float f) : base(inst) {
  3408. fVal = f;
  3409. size += 4;
  3410. }
  3411. internal sealed override void Write(FileImage output) {
  3412. base.Write(output);
  3413. output.Write(fVal);
  3414. }
  3415. }
  3416. internal class DoubleInstr : Instr {
  3417. double val;
  3418. internal DoubleInstr(int inst, double d) : base(inst) {
  3419. val = d;
  3420. size += 8;
  3421. }
  3422. internal sealed override void Write(FileImage output) {
  3423. base.Write(output);
  3424. output.Write(val);
  3425. }
  3426. }
  3427. internal class StringInstr : Instr {
  3428. string val;
  3429. byte[] bval;
  3430. uint strIndex;
  3431. internal StringInstr(int inst, string str) : base(inst) {
  3432. val = str;
  3433. size += 4;
  3434. }
  3435. internal StringInstr (int inst, byte[] str) : base (inst) {
  3436. bval = str;
  3437. size += 4;
  3438. }
  3439. internal sealed override bool Check(MetaData md) {
  3440. if (val != null)
  3441. strIndex = md.AddToUSHeap(val);
  3442. else
  3443. strIndex = md.AddToUSHeap (bval);
  3444. return false;
  3445. }
  3446. internal sealed override void Write(FileImage output) {
  3447. base.Write(output);
  3448. output.Write(USHeapIndex | strIndex);
  3449. }
  3450. }
  3451. internal class LabelInstr : CILInstruction {
  3452. CILLabel label;
  3453. internal LabelInstr(CILLabel lab) {
  3454. label = lab;
  3455. label.AddLabelInstr(this);
  3456. }
  3457. }
  3458. internal class FieldInstr : Instr {
  3459. Field field;
  3460. internal FieldInstr(int inst, Field f) : base(inst) {
  3461. field = f;
  3462. size += 4;
  3463. }
  3464. internal sealed override void Write(FileImage output) {
  3465. base.Write(output);
  3466. output.Write(field.Token());
  3467. }
  3468. }
  3469. internal class MethInstr : Instr {
  3470. Method meth;
  3471. internal MethInstr(int inst, Method m) : base(inst) {
  3472. meth = m;
  3473. size += 4;
  3474. }
  3475. internal sealed override void Write(FileImage output) {
  3476. base.Write(output);
  3477. output.Write(meth.Token());
  3478. }
  3479. }
  3480. internal class SigInstr : Instr {
  3481. CalliSig signature;
  3482. internal SigInstr(int inst, CalliSig sig) : base(inst) {
  3483. signature = sig;
  3484. size += 4;
  3485. }
  3486. internal sealed override bool Check(MetaData md) {
  3487. md.AddToTable(MDTable.StandAloneSig,signature);
  3488. signature.BuildTables(md);
  3489. return false;
  3490. }
  3491. internal sealed override void Write(FileImage output) {
  3492. base.Write(output);
  3493. output.Write(signature.Token());
  3494. }
  3495. }
  3496. internal class TypeInstr : Instr {
  3497. MetaDataElement theType;
  3498. internal TypeInstr(int inst, Type aType, MetaData md) : base(inst) {
  3499. theType = aType.GetTypeSpec(md);
  3500. size += 4;
  3501. }
  3502. internal sealed override void Write(FileImage output) {
  3503. base.Write(output);
  3504. output.Write(theType.Token());
  3505. }
  3506. }
  3507. internal class BranchInstr : Instr {
  3508. CILLabel dest;
  3509. private bool shortVer = true;
  3510. private static readonly byte longInstrOffset = 13;
  3511. private int target = 0;
  3512. internal BranchInstr(int inst, CILLabel dst) : base(inst) {
  3513. dest = dst;
  3514. dest.AddBranch(this);
  3515. size++;
  3516. if (inst >= (int) BranchOp.br && inst != (int) BranchOp.leave_s) {
  3517. shortVer = false;
  3518. size += 3;
  3519. }
  3520. }
  3521. internal sealed override bool Check(MetaData md) {
  3522. target = (int)dest.GetLabelOffset() - (int)(offset + size);
  3523. return false;
  3524. }
  3525. internal sealed override void Write(FileImage output) {
  3526. base.Write(output);
  3527. if (shortVer)
  3528. output.Write((sbyte)target);
  3529. else
  3530. output.Write(target);
  3531. }
  3532. }
  3533. internal class SwitchInstr : Instr {
  3534. CILLabel[] cases;
  3535. uint numCases = 0;
  3536. internal SwitchInstr(int inst, CILLabel[] dsts) : base(inst) {
  3537. cases = dsts;
  3538. if (cases != null) numCases = (uint)cases.Length;
  3539. size += 4 + (numCases * 4);
  3540. for (int i=0; i < numCases; i++) {
  3541. cases[i].AddBranch(this);
  3542. }
  3543. }
  3544. internal sealed override void Write(FileImage output) {
  3545. base.Write(output);
  3546. output.Write(numCases);
  3547. for (int i=0; i < numCases; i++) {
  3548. int target = (int)cases[i].GetLabelOffset() - (int)(offset + size);
  3549. output.Write(target);
  3550. }
  3551. }
  3552. }
  3553. /**************************************************************************/
  3554. public class GenericParameter : MetaDataElement
  3555. {
  3556. MetaDataElement owner;
  3557. MetaData metadata;
  3558. string name;
  3559. uint nameIx;
  3560. short index;
  3561. internal GenericParameter (ClassDef owner, MetaData metadata,
  3562. short index, string name) : this (owner, metadata, index, name, true)
  3563. {
  3564. }
  3565. internal GenericParameter (MethodDef owner, MetaData metadata,
  3566. short index, string name) : this (owner, metadata, index, name, true)
  3567. {
  3568. }
  3569. private GenericParameter (MetaDataElement owner, MetaData metadata,
  3570. short index, string name, bool nadda)
  3571. {
  3572. this.owner = owner;
  3573. this.metadata = metadata;
  3574. this.index = index;
  3575. tabIx = MDTable.GenericParam;
  3576. this.name = name;
  3577. }
  3578. public void AddConstraint (Type constraint) {
  3579. metadata.AddToTable (MDTable.GenericParamConstraint,
  3580. new GenericParamConstraint (this, constraint));
  3581. }
  3582. internal sealed override uint Size(MetaData md) {
  3583. return (uint) (4 +
  3584. md.CodedIndexSize(CIx.TypeOrMethodDef) +
  3585. 4 +
  3586. md.TableIndexSize(MDTable.TypeDef));
  3587. }
  3588. internal sealed override void BuildTables(MetaData md) {
  3589. if (done) return;
  3590. nameIx = md.AddToStringsHeap(name);
  3591. done = true;
  3592. }
  3593. internal sealed override void Write(FileImage output) {
  3594. output.Write ((short) index);
  3595. output.Write ((short) 0);
  3596. output.WriteCodedIndex(CIx.TypeOrMethodDef, owner);
  3597. output.Write ((uint) nameIx);
  3598. output.WriteIndex(MDTable.TypeDef,owner.Row);
  3599. }
  3600. }
  3601. internal class GenericParamConstraint : MetaDataElement
  3602. {
  3603. GenericParameter param;
  3604. Type type;
  3605. public GenericParamConstraint (GenericParameter param, Type type) {
  3606. this.param = param;
  3607. this.type = type;
  3608. tabIx = MDTable.GenericParamConstraint;
  3609. }
  3610. internal sealed override uint Size(MetaData md) {
  3611. return (uint) (md.TableIndexSize(MDTable.GenericParam) +
  3612. md.CodedIndexSize(CIx.TypeDefOrRef));
  3613. }
  3614. internal sealed override void Write(FileImage output) {
  3615. output.WriteIndex(MDTable.GenericParam, param.Row);
  3616. output.WriteCodedIndex(CIx.TypeDefOrRef, type);
  3617. }
  3618. }
  3619. internal class MethodSpec : MetaDataElement
  3620. {
  3621. Method meth;
  3622. GenericMethodSig g_sig;
  3623. uint sidx;
  3624. internal MethodSpec (Method meth, GenericMethodSig g_sig) {
  3625. this.meth = meth;
  3626. this.g_sig = g_sig;
  3627. tabIx = MDTable.MethodSpec;
  3628. }
  3629. internal sealed override void BuildTables (MetaData md) {
  3630. if (done) return;
  3631. sidx = g_sig.GetSigIx (md);
  3632. done = true;
  3633. }
  3634. internal sealed override uint Size (MetaData md) {
  3635. return (uint) (md.CodedIndexSize(CIx.MethodDefOrRef) +
  3636. md.BlobIndexSize ());
  3637. }
  3638. internal sealed override void Write (FileImage output) {
  3639. output.WriteCodedIndex (CIx.MethodDefOrRef, meth);
  3640. output.BlobIndex (sidx);
  3641. }
  3642. }
  3643. /**************************************************************************/
  3644. /// <summary>
  3645. /// Descriptor for interface implemented by a class
  3646. /// </summary>
  3647. public class InterfaceImpl: MetaDataElement
  3648. {
  3649. ClassDef theClass;
  3650. Class theInterface;
  3651. internal InterfaceImpl(ClassDef theClass, Class theInterface) {
  3652. this.theClass = theClass;
  3653. this.theInterface = theInterface;
  3654. tabIx = MDTable.InterfaceImpl;
  3655. }
  3656. internal sealed override uint Size(MetaData md) {
  3657. return md.TableIndexSize(MDTable.TypeDef) +
  3658. md.CodedIndexSize(CIx.TypeDefOrRef);
  3659. }
  3660. internal sealed override void Write(FileImage output) {
  3661. output.WriteIndex(MDTable.TypeDef,theClass.Row);
  3662. output.WriteCodedIndex(CIx.TypeDefOrRef,theInterface);
  3663. }
  3664. internal sealed override uint GetCodedIx(CIx code) { return 5; }
  3665. }
  3666. /**************************************************************************/
  3667. /// <summary>
  3668. /// Descriptor for a local of a method
  3669. /// </summary>
  3670. public class Local
  3671. {
  3672. private static readonly byte Pinned = 0x45;
  3673. string name;
  3674. Type type;
  3675. bool pinned = false, byref = false;
  3676. /// <summary>
  3677. /// Create a new local variable
  3678. /// </summary>
  3679. /// <param name="lName">name of the local variable</param>
  3680. /// <param name="lType">type of the local variable</param>
  3681. public Local(string lName, Type lType) {
  3682. name = lName;
  3683. type = lType;
  3684. }
  3685. /// <summary>
  3686. /// Create a new local variable that is byref and/or pinned
  3687. /// </summary>
  3688. /// <param name="lName">local name</param>
  3689. /// <param name="lType">local type</param>
  3690. /// <param name="byRef">is byref</param>
  3691. /// <param name="isPinned">has pinned attribute</param>
  3692. public Local(string lName, Type lType, bool byRef, bool isPinned)
  3693. {
  3694. name = lName;
  3695. type = lType;
  3696. byref = byRef;
  3697. pinned = isPinned;
  3698. }
  3699. internal void TypeSig(MemoryStream str) {
  3700. if (pinned) str.WriteByte(Pinned);
  3701. type.TypeSig(str);
  3702. }
  3703. }
  3704. /**************************************************************************/
  3705. /// <summary>
  3706. /// Descriptor for the locals for a method
  3707. /// </summary>
  3708. public class LocalSig : Signature
  3709. {
  3710. private static readonly byte LocalSigByte = 0x7;
  3711. Local[] locals;
  3712. public LocalSig(Local[] locals) {
  3713. this.locals = locals;
  3714. tabIx = MDTable.StandAloneSig;
  3715. }
  3716. internal sealed override void BuildTables(MetaData md) {
  3717. if (done) return;
  3718. MemoryStream sig = new MemoryStream();
  3719. sig.WriteByte(LocalSigByte);
  3720. MetaData.CompressNum((uint)locals.Length,sig);
  3721. for (int i=0; i < locals.Length; i++) {
  3722. ((Local)locals[i]).TypeSig(sig);
  3723. }
  3724. sigIx = md.AddToBlobHeap(sig.ToArray());
  3725. done = true;
  3726. }
  3727. }
  3728. /**************************************************************************/
  3729. /// <summary>
  3730. /// Descriptor for resources used in this PE file NOT YET IMPLEMENTED
  3731. /// </summary>
  3732. public class ManifestResource : MetaDataElement
  3733. {
  3734. private static readonly uint PublicResource = 0x1;
  3735. private static readonly uint PrivateResource = 0x2;
  3736. string mrName;
  3737. MetaDataElement rRef;
  3738. int fileOffset;
  3739. uint nameIx = 0;
  3740. uint flags = 0;
  3741. public ManifestResource(string name, bool isPub, FileRef fileRef) {
  3742. mrName = name;
  3743. if (isPub) flags = PublicResource;
  3744. else flags = PrivateResource;
  3745. rRef = fileRef;
  3746. tabIx = MDTable.ManifestResource;
  3747. throw(new NotYetImplementedException("Manifest Resources "));
  3748. }
  3749. public ManifestResource(string name, bool isPub, FileRef fileRef,
  3750. int fileIx) {
  3751. mrName = name;
  3752. if (isPub) flags = PublicResource;
  3753. else flags = PrivateResource;
  3754. rRef = fileRef;
  3755. fileOffset = fileIx;
  3756. }
  3757. public ManifestResource(string name, bool isPub, AssemblyRef assemRef) {
  3758. mrName = name;
  3759. if (isPub) flags = PublicResource;
  3760. else flags = PrivateResource;
  3761. rRef = assemRef;
  3762. }
  3763. internal sealed override void BuildTables(MetaData md) {
  3764. if (done) return;
  3765. nameIx = md.AddToStringsHeap(mrName);
  3766. done = true;
  3767. }
  3768. internal sealed override uint Size(MetaData md) {
  3769. return 8 + md.StringsIndexSize() +
  3770. md.CodedIndexSize(CIx.Implementation);
  3771. }
  3772. internal sealed override void Write(FileImage output) {
  3773. output.Write(fileOffset);
  3774. output.Write(flags);
  3775. output.StringsIndex(nameIx);
  3776. output.WriteCodedIndex(CIx.Implementation,rRef);
  3777. }
  3778. internal sealed override uint GetCodedIx(CIx code) { return 18; }
  3779. }
  3780. /**************************************************************************/
  3781. /// <summary>
  3782. /// Base class for elements in the PropertyMap, EventMap and
  3783. /// NestedClass MetaData tables
  3784. /// </summary>
  3785. public class MapElem : MetaDataElement
  3786. {
  3787. ClassDef parent;
  3788. uint elemIx;
  3789. MDTable elemTable;
  3790. internal MapElem(ClassDef par, uint elIx, MDTable elemTab) {
  3791. parent = par;
  3792. elemIx = elIx;
  3793. elemTable = elemTab;
  3794. }
  3795. internal sealed override uint Size(MetaData md) {
  3796. return md.TableIndexSize(MDTable.TypeDef) + md.TableIndexSize(elemTable);
  3797. }
  3798. internal sealed override void Write(FileImage output) {
  3799. output.WriteIndex(MDTable.TypeDef,parent.Row);
  3800. output.WriteIndex(elemTable,elemIx);
  3801. }
  3802. }
  3803. /**************************************************************************/
  3804. /// <summary>
  3805. /// Base class for field/methods (member of a class)
  3806. /// </summary>
  3807. public abstract class Member : MetaDataElement
  3808. {
  3809. protected string name;
  3810. protected uint nameIx = 0, sigIx = 0;
  3811. internal Member(string memName)
  3812. {
  3813. name = memName;
  3814. tabIx = MDTable.MemberRef;
  3815. }
  3816. }
  3817. /**************************************************************************/
  3818. /// <summary>
  3819. /// MetaData
  3820. /// Root (20 bytes + UTF-8 Version String + quad align padding)
  3821. /// StreamHeaders (8 bytes + null terminated name string + quad align padding)
  3822. /// Streams
  3823. /// #~ (always present - holds metadata tables)
  3824. /// #Strings (always present - holds identifier strings)
  3825. /// #US (Userstring heap)
  3826. /// #Blob (signature blobs)
  3827. /// #GUID (guids for assemblies or Modules)
  3828. /// </summary>
  3829. public class MetaData
  3830. {
  3831. private static readonly int[] CIxShiftMap = {2,2,5,1,2,3,1,1,1,2,3,2,1};
  3832. private static readonly byte StringsHeapMask = 0x1;
  3833. private static readonly byte GUIDHeapMask = 0x2;
  3834. private static readonly byte BlobHeapMask = 0x4;
  3835. private static readonly uint MetaDataSignature = 0x424A5342;
  3836. private static readonly uint maxSmlIxSize = 0xFFFF;
  3837. private static readonly uint max1BitSmlIx = 0x7FFF;
  3838. private static readonly uint max2BitSmlIx = 0x3FFF;
  3839. private static readonly uint max3BitSmlIx = 0x1FFF;
  3840. private static readonly uint max5BitSmlIx = 0x7FF;
  3841. // NOTE: version and stream name strings MUST always be quad padded
  3842. private static readonly string version = "v1.0.3705\0\0\0";
  3843. private static readonly char[] tildeName = {'#','~','\0','\0'};
  3844. private static readonly char[] stringsName = {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'};
  3845. private static readonly char[] usName = {'#','U','S','\0'};
  3846. private static readonly char[] guidName = {'#','G','U','I','D','\0','\0','\0'};
  3847. private static readonly char[] blobName = {'#','B','l','o','b','\0','\0','\0'};
  3848. private static readonly uint MetaDataHeaderSize = 20 + (uint)version.Length;
  3849. private static readonly uint TildeHeaderSize = 24;
  3850. private static readonly uint StreamHeaderSize = 8;
  3851. private static readonly uint numMetaDataTables = (int)MDTable.GenericParamConstraint + 1;
  3852. private static readonly uint tildeHeaderSize = 8 + (uint)tildeName.Length;
  3853. MetaDataStream strings, us, guid, blob;
  3854. MetaDataStream[] streams = new MetaDataStream[5];
  3855. uint numStreams = 5;
  3856. uint tildeTide = 0, tildePadding = 0, tildeStart = 0;
  3857. uint numTables = 0;
  3858. ArrayList[] metaDataTables = new ArrayList[numMetaDataTables];
  3859. ArrayList byteCodes = new ArrayList();
  3860. uint codeSize = 0, codeStart, byteCodePadding = 0, metaDataSize = 0;
  3861. ulong valid = 0, /*sorted = 0x000002003301FA00;*/ sorted = 0;
  3862. bool[] largeIx = new bool[numMetaDataTables];
  3863. bool[] lgeCIx = new bool[(int)CIx.MaxCIx];
  3864. bool largeStrings = false, largeUS = false, largeGUID = false, largeBlob = false;
  3865. private FileImage file;
  3866. private byte heapSizes = 0;
  3867. MetaDataElement entryPoint;
  3868. BinaryWriter output;
  3869. public MSCorLib mscorlib;
  3870. private TypeSpec[] systemTypeSpecs = new TypeSpec[PrimitiveType.NumSystemTypes];
  3871. long mdStart;
  3872. private ArrayList cattr_list;
  3873. internal MetaData(FileImage file) {
  3874. // tilde = new MetaDataStream(tildeName,false,0);
  3875. this.file = file;
  3876. strings = new MetaDataStream(stringsName,new UTF8Encoding(),true);
  3877. us = new MetaDataStream(usName,new UnicodeEncoding(),true);
  3878. guid = new MetaDataStream(guidName,false);
  3879. blob = new MetaDataStream(blobName,true);
  3880. streams[1] = strings;
  3881. streams[2] = us;
  3882. streams[3] = guid;
  3883. streams[4] = blob;
  3884. for (int i=0; i < numMetaDataTables; i++) {
  3885. largeIx[i] = false;
  3886. }
  3887. for (int i=0; i < lgeCIx.Length; i++) {
  3888. lgeCIx[i] = false;
  3889. }
  3890. mscorlib = new MSCorLib(this);
  3891. }
  3892. internal TypeSpec GetPrimitiveTypeSpec(int ix) {
  3893. return systemTypeSpecs[ix];
  3894. }
  3895. internal void SetPrimitiveTypeSpec(int ix, TypeSpec typeSpec) {
  3896. systemTypeSpecs[ix] = typeSpec;
  3897. }
  3898. internal uint Size() {
  3899. return metaDataSize;
  3900. }
  3901. private void CalcHeapSizes ()
  3902. {
  3903. if (strings.LargeIx()) {
  3904. largeStrings = true;
  3905. heapSizes |= StringsHeapMask;
  3906. }
  3907. if (guid.LargeIx()) {
  3908. largeGUID = true;
  3909. heapSizes |= GUIDHeapMask;
  3910. }
  3911. if (blob.LargeIx()) {
  3912. largeBlob = true;
  3913. heapSizes |= BlobHeapMask;
  3914. }
  3915. largeUS = us.LargeIx();
  3916. }
  3917. internal void StreamSize(byte mask) {
  3918. heapSizes |= mask;
  3919. }
  3920. internal uint AddToUSHeap(string str) {
  3921. if (str == null) return 0;
  3922. return us.Add(str,true);
  3923. }
  3924. internal uint AddToUSHeap(byte[] str) {
  3925. if (str == null) return 0;
  3926. return us.Add (str, true);
  3927. }
  3928. internal uint AddToStringsHeap(string str) {
  3929. if ((str == null) || (str.CompareTo("") == 0)) return 0;
  3930. return strings.Add(str,false);
  3931. }
  3932. internal uint AddToGUIDHeap(Guid guidNum) {
  3933. return guid.Add(guidNum, false);
  3934. }
  3935. internal uint AddToBlobHeap(byte[] blobBytes) {
  3936. if (blobBytes == null) return 0;
  3937. return blob.Add(blobBytes, true);
  3938. }
  3939. internal uint AddToBlobHeap(byte val) {
  3940. return blob.Add(val, true);
  3941. }
  3942. internal uint AddToBlobHeap(sbyte val) {
  3943. return blob.Add(val, true);
  3944. }
  3945. internal uint AddToBlobHeap(ushort val) {
  3946. return blob.Add(val, true);
  3947. }
  3948. internal uint AddToBlobHeap(short val) {
  3949. return blob.Add(val, true);
  3950. }
  3951. internal uint AddToBlobHeap(uint val) {
  3952. return blob.Add(val, true);
  3953. }
  3954. internal uint AddToBlobHeap(int val) {
  3955. return blob.Add(val, true);
  3956. }
  3957. internal uint AddToBlobHeap(ulong val) {
  3958. return blob.Add(val, true);
  3959. }
  3960. internal uint AddToBlobHeap(long val) {
  3961. return blob.Add(val, true);
  3962. }
  3963. internal uint AddToBlobHeap(float val) {
  3964. return blob.Add(val, true);
  3965. }
  3966. internal uint AddToBlobHeap(double val) {
  3967. return blob.Add(val, true);
  3968. }
  3969. internal uint AddToBlobHeap(string val) {
  3970. return blob.Add(val,true);
  3971. }
  3972. internal void AddCustomAttribute (CustomAttribute cattr)
  3973. {
  3974. if (cattr_list == null)
  3975. cattr_list = new ArrayList ();
  3976. cattr_list.Add (cattr);
  3977. }
  3978. private ArrayList GetTable(MDTable tableIx) {
  3979. int tabIx = (int)tableIx;
  3980. if (metaDataTables[tabIx] == null) {
  3981. metaDataTables[tabIx] = new ArrayList();
  3982. valid |= ((ulong)0x1 << tabIx);
  3983. // Console.WriteLine("after creating table " + tableIx + "(" + tabIx + ") valid = " + valid);
  3984. numTables++;
  3985. }
  3986. return metaDataTables[tabIx];
  3987. }
  3988. internal void AddToTable(MDTable tableIx, MetaDataElement elem) {
  3989. if (elem.Row > 0) {
  3990. // Console.Out.WriteLine("ERROR - element already in table " + tableIx);
  3991. return;
  3992. }
  3993. // updates Row field of the element
  3994. // Console.WriteLine("Adding element to table " + (uint)tableIx);
  3995. ArrayList table = GetTable(tableIx);
  3996. elem.Row = (uint)table.Count + 1;
  3997. table.Add(elem);
  3998. }
  3999. internal uint TableIndex(MDTable tableIx) {
  4000. if (metaDataTables[(int)tableIx] == null) return 1;
  4001. return (uint)metaDataTables[(int)tableIx].Count+1;
  4002. }
  4003. internal uint AddCode(CILInstructions byteCode) {
  4004. byteCodes.Add(byteCode);
  4005. uint offset = codeSize + codeStart;
  4006. codeSize += byteCode.GetCodeSize();
  4007. return offset;
  4008. }
  4009. internal void SetEntryPoint(MetaDataElement ep) {
  4010. entryPoint = ep;
  4011. }
  4012. internal void AddData(DataConstant cVal) {
  4013. file.AddInitData(cVal);
  4014. }
  4015. internal static void CompressNum(uint val, MemoryStream sig) {
  4016. if (val < 0x7F) {
  4017. sig.WriteByte((byte)val);
  4018. } else if (val < 0x3FFF) {
  4019. byte b1 = (byte)((val >> 8) | 0x80);
  4020. byte b2 = (byte)(val & FileImage.iByteMask[0]);
  4021. sig.WriteByte(b1);
  4022. sig.WriteByte(b2);
  4023. } else {
  4024. byte b1 = (byte)((val >> 24) | 0xC0);
  4025. byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
  4026. byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
  4027. byte b4 = (byte)(val & FileImage.iByteMask[0]);
  4028. sig.WriteByte(b1);
  4029. sig.WriteByte(b2);
  4030. sig.WriteByte(b3);
  4031. sig.WriteByte(b4);
  4032. }
  4033. }
  4034. internal uint CodeSize() {
  4035. return codeSize + byteCodePadding;
  4036. }
  4037. internal uint StringsIndexSize() {
  4038. if (largeStrings) return 4;
  4039. return 2;
  4040. }
  4041. internal uint GUIDIndexSize() {
  4042. if (largeGUID) return 4;
  4043. return 2;
  4044. }
  4045. internal uint USIndexSize() {
  4046. if (largeUS) return 4;
  4047. return 2;
  4048. }
  4049. internal uint BlobIndexSize() {
  4050. if (largeBlob) return 4;
  4051. return 2;
  4052. }
  4053. internal uint CodedIndexSize(CIx code) {
  4054. if (lgeCIx[(uint)code]) return 4;
  4055. return 2;
  4056. }
  4057. internal uint TableIndexSize(MDTable tabIx) {
  4058. if (largeIx[(uint)tabIx]) return 4;
  4059. return 2;
  4060. }
  4061. private void SetIndexSizes() {
  4062. for (int i=0; i < numMetaDataTables; i++) {
  4063. if (metaDataTables[i] == null)
  4064. continue;
  4065. uint count = (uint)metaDataTables[i].Count;
  4066. if (count > maxSmlIxSize)
  4067. largeIx[i] = true;
  4068. MDTable tabIx = (MDTable)i;
  4069. if (count > max5BitSmlIx) {
  4070. lgeCIx[(int)CIx.HasCustomAttr] = true;
  4071. }
  4072. if (count > max3BitSmlIx) {
  4073. if ((tabIx == MDTable.TypeRef) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.Method) || (tabIx == MDTable.TypeSpec) || (tabIx == MDTable.Field))
  4074. lgeCIx[(int)CIx.CustomAttributeType] = true;
  4075. if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
  4076. lgeCIx[(int)CIx.MemberRefParent] = true;
  4077. }
  4078. if (count > max2BitSmlIx) {
  4079. if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param) || (tabIx == MDTable.Property))
  4080. lgeCIx[(int)CIx.HasConst] = true;
  4081. if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.TypeRef) || (tabIx == MDTable.TypeSpec))
  4082. lgeCIx[(int)CIx.TypeDefOrRef] = true;
  4083. if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method) || (tabIx == MDTable.Assembly))
  4084. lgeCIx[(int)CIx.HasDeclSecurity] = true;
  4085. if ((tabIx == MDTable.File) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.ExportedType))
  4086. lgeCIx[(int)CIx.Implementation] = true;
  4087. if ((tabIx == MDTable.Module) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.TypeRef))
  4088. lgeCIx[(int)CIx.ResolutionScope] = true;
  4089. }
  4090. if (count > max1BitSmlIx) {
  4091. if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param))
  4092. lgeCIx[(int)CIx.HasFieldMarshal] = true;
  4093. if ((tabIx == MDTable.Event) || (tabIx == MDTable.Property))
  4094. lgeCIx[(int)CIx.HasSemantics] = true;
  4095. if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
  4096. lgeCIx[(int)CIx.MethodDefOrRef] = true;
  4097. if ((tabIx == MDTable.Field) || (tabIx == MDTable.Method))
  4098. lgeCIx[(int)CIx.MemberForwarded] = true;
  4099. if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method))
  4100. lgeCIx[(int)CIx.TypeOrMethodDef] = true;
  4101. }
  4102. }
  4103. }
  4104. private void SetStreamOffsets() {
  4105. uint sizeOfHeaders = StreamHeaderSize + (uint)tildeName.Length;
  4106. for (int i=1; i < numStreams; i++) {
  4107. sizeOfHeaders += streams[i].headerSize();
  4108. }
  4109. metaDataSize = MetaDataHeaderSize + sizeOfHeaders;
  4110. tildeStart = metaDataSize;
  4111. metaDataSize += tildeTide + tildePadding;
  4112. for (int i=1; i < numStreams; i++) {
  4113. streams[i].Start = metaDataSize;
  4114. metaDataSize += streams[i].Size();
  4115. streams[i].WriteDetails();
  4116. }
  4117. }
  4118. internal void CalcTildeStreamSize() {
  4119. CalcHeapSizes ();
  4120. //tilde.SetIndexSizes(strings.LargeIx(),us.LargeIx(),guid.LargeIx(),blob.LargeIx());
  4121. tildeTide = TildeHeaderSize;
  4122. tildeTide += 4 * numTables;
  4123. //Console.WriteLine("Tilde header + sizes = " + tildeTide);
  4124. for (int i=0; i < numMetaDataTables; i++) {
  4125. if (metaDataTables[i] != null) {
  4126. ArrayList table = metaDataTables[i];
  4127. // Console.WriteLine("Meta data table " + i + " at offset " + tildeTide);
  4128. tildeTide += (uint)table.Count * ((MetaDataElement)table[0]).Size(this);
  4129. // Console.WriteLine("Metadata table " + i + " has size " + table.Count);
  4130. // Console.WriteLine("tildeTide = " + tildeTide);
  4131. }
  4132. }
  4133. if ((tildeTide % 4) != 0) tildePadding = 4 - (tildeTide % 4);
  4134. //Console.WriteLine("tildePadding = " + tildePadding);
  4135. }
  4136. internal void WriteTildeStream(FileImage output) {
  4137. long startTilde = output.Seek(0,SeekOrigin.Current);
  4138. output.Write((uint)0); // Reserved
  4139. output.Write((byte)1); // MajorVersion
  4140. output.Write((byte)0); // MinorVersion
  4141. output.Write(heapSizes);
  4142. output.Write((byte)1); // Reserved
  4143. output.Write(valid);
  4144. output.Write(sorted);
  4145. for (int i=0; i < numMetaDataTables; i++) {
  4146. if (metaDataTables[i] != null) {
  4147. uint count = (uint)metaDataTables[i].Count;
  4148. output.Write(count);
  4149. }
  4150. }
  4151. long tabStart = output.Seek(0,SeekOrigin.Current);
  4152. // Console.WriteLine("Starting metaData tables at " + tabStart);
  4153. for (int i=0; i < numMetaDataTables; i++) {
  4154. if (metaDataTables[i] != null) {
  4155. // Console.WriteLine("Starting metaData table " + i + " at " + (output.Seek(0,SeekOrigin.Current) - startTilde));
  4156. ArrayList table = metaDataTables[i];
  4157. for (int j=0; j < table.Count; j++) {
  4158. ((MetaDataElement)table[j]).Write(output);
  4159. }
  4160. }
  4161. }
  4162. // Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));
  4163. for (int i=0; i < tildePadding; i++) output.Write((byte)0);
  4164. }
  4165. private void BuildTable(ArrayList table) {
  4166. if (table == null) return;
  4167. for (int j=0; j < table.Count; j++) {
  4168. ((MetaDataElement)table[j]).BuildTables(this);
  4169. }
  4170. }
  4171. internal void BuildMetaData(uint codeStartOffset) {
  4172. codeStart = codeStartOffset;
  4173. BuildTable(metaDataTables[(int)MDTable.TypeDef]);
  4174. BuildTable(metaDataTables[(int)MDTable.MemberRef]);
  4175. BuildTable(metaDataTables[(int)MDTable.GenericParam]);
  4176. BuildTable(metaDataTables[(int)MDTable.MethodSpec]);
  4177. BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
  4178. if (cattr_list != null) {
  4179. foreach (CustomAttribute cattr in cattr_list)
  4180. cattr.BuildTables (this);
  4181. }
  4182. /* for (int i=0; i < metaDataTables.Length; i++) {
  4183. ArrayList table = metaDataTables[i];
  4184. if (table != null) {
  4185. for (int j=0; j < table.Count; j++) {
  4186. ((MetaDataElement)table[j]).BuildTables(this);
  4187. }
  4188. }
  4189. }
  4190. */
  4191. SetIndexSizes();
  4192. for (int i=1; i < numStreams; i++) {
  4193. streams[i].EndStream();
  4194. }
  4195. CalcTildeStreamSize();
  4196. SetStreamOffsets();
  4197. byteCodePadding = NumToAlign(codeSize,4);
  4198. if (entryPoint != null) file.SetEntryPoint(entryPoint.Token());
  4199. }
  4200. internal void WriteByteCodes(FileImage output) {
  4201. for (int i=0; i < byteCodes.Count; i++) {
  4202. ((CILInstructions)byteCodes[i]).Write(output);
  4203. }
  4204. for (int i=0; i < byteCodePadding; i++) {
  4205. output.Write((byte)0);
  4206. }
  4207. }
  4208. internal void WriteMetaData(FileImage output) {
  4209. this.output = output;
  4210. mdStart = output.Seek(0,SeekOrigin.Current);
  4211. // Console.WriteLine("Writing metaData at " + Hex.Long(mdStart));
  4212. output.Write(MetaDataSignature);
  4213. output.Write((short)1); // Major Version
  4214. output.Write((short)1); // Minor Version ECMA = 0, PEFiles = 1
  4215. output.Write(0); // Reserved
  4216. output.Write(version.Length);
  4217. output.Write(version.ToCharArray()); // version string is already zero padded
  4218. output.Write((short)0);
  4219. output.Write((ushort)numStreams);
  4220. // write tilde header
  4221. output.Write(tildeStart);
  4222. output.Write(tildeTide + tildePadding);
  4223. output.Write(tildeName);
  4224. for (int i=1; i < numStreams; i++) streams[i].WriteHeader(output);
  4225. // Console.WriteLine("Writing tilde stream at " + output.Seek(0,SeekOrigin.Current) + " = " + tildeStart);
  4226. WriteTildeStream(output);
  4227. for (int i=1; i < numStreams; i++) streams[i].Write(output);
  4228. // Console.WriteLine("Finished Writing metaData at " + output.Seek(0,SeekOrigin.Current));
  4229. }
  4230. internal bool LargeStringsIndex() { return strings.LargeIx(); }
  4231. internal bool LargeGUIDIndex() { return guid.LargeIx(); }
  4232. internal bool LargeUSIndex() { return us.LargeIx(); }
  4233. internal bool LargeBlobIndex() { return blob.LargeIx(); }
  4234. internal bool LargeIx(MDTable tabIx) { return largeIx[(uint)tabIx]; }
  4235. private uint NumToAlign(uint val, uint alignVal) {
  4236. if ((val % alignVal) == 0) return 0;
  4237. return alignVal - (val % alignVal);
  4238. }
  4239. internal void WriteCodedIndex(CIx code, MetaDataElement elem, FileImage output) {
  4240. uint ix = 0;
  4241. if (elem != null) {
  4242. ix = (elem.Row << CIxShiftMap[(uint)code]) | elem.GetCodedIx(code);
  4243. // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);
  4244. //} else {
  4245. // Console.WriteLine("elem for coded index is null");
  4246. }
  4247. if (lgeCIx[(uint)code])
  4248. output.Write(ix);
  4249. else
  4250. output.Write((ushort)ix);
  4251. }
  4252. }
  4253. /**************************************************************************/
  4254. /// <summary>
  4255. /// Base class for all Meta Data table elements
  4256. /// </summary>
  4257. public abstract class MetaDataElement
  4258. {
  4259. protected ArrayList customAttributes;
  4260. private uint row = 0;
  4261. protected bool done = false;
  4262. protected MDTable tabIx;
  4263. internal MetaDataElement() { }
  4264. public uint Row {
  4265. get {
  4266. return row;
  4267. }
  4268. set {
  4269. if (row == 0) row = value;
  4270. }
  4271. }
  4272. internal virtual uint GetCodedIx(CIx code) { return 0; }
  4273. /// <summary>
  4274. /// Add a custom attribute to this item
  4275. /// </summary>
  4276. /// <param name="ctorMeth">the constructor method for this attribute</param>
  4277. /// <param name="val">the byte value of the parameters</param>
  4278. public void AddCustomAttribute(Method ctorMeth, byte[] val) {
  4279. if (customAttributes == null) {
  4280. customAttributes = new ArrayList();
  4281. }
  4282. customAttributes.Add(new CustomAttribute(this,ctorMeth,val));
  4283. }
  4284. /// <summary>
  4285. /// Add a custom attribute to this item
  4286. /// </summary>
  4287. /// <param name="ctorMeth">the constructor method for this attribute</param>
  4288. /// <param name="val">the constant values of the parameters</param>
  4289. public void AddCustomAttribute(Method ctorMeth, Constant[] cVals) {
  4290. if (customAttributes == null) {
  4291. customAttributes = new ArrayList();
  4292. }
  4293. // customAttributes.Add(new CustomAttribute(this,ctorMeth,cVals));
  4294. }
  4295. internal uint Token() {
  4296. return (((uint)tabIx << 24) | row);
  4297. }
  4298. internal virtual void BuildTables(MetaData md) {
  4299. done = true;
  4300. }
  4301. internal virtual uint Size(MetaData md) {
  4302. return 0;
  4303. }
  4304. internal virtual void Write(FileImage output) { }
  4305. }
  4306. /**************************************************************************/
  4307. /// <summary>
  4308. /// Stream in the Meta Data (#Strings, #US, #Blob and #GUID)
  4309. /// </summary>
  4310. internal class MetaDataStream : BinaryWriter
  4311. {
  4312. private static readonly uint StreamHeaderSize = 8;
  4313. private static uint maxSmlIxSize = 0xFFFF;
  4314. private uint start = 0;
  4315. uint size = 0, tide = 1;
  4316. bool largeIx = false;
  4317. uint sizeOfHeader;
  4318. char[] name;
  4319. Hashtable htable = new Hashtable();
  4320. Hashtable btable = new Hashtable (new ByteArrayHashCodeProvider (), new ByteArrayComparer ());
  4321. internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream()) {
  4322. if (addInitByte) { Write((byte)0); size = 1; }
  4323. this.name = name;
  4324. sizeOfHeader = StreamHeaderSize + (uint)name.Length;
  4325. }
  4326. internal MetaDataStream(char[] name, System.Text.Encoding enc, bool addInitByte) : base(new MemoryStream(),enc) {
  4327. if (addInitByte) { Write((byte)0); size = 1; }
  4328. this.name = name;
  4329. sizeOfHeader = StreamHeaderSize + (uint)name.Length;
  4330. }
  4331. public uint Start {
  4332. get {
  4333. return start;
  4334. }
  4335. set {
  4336. start = value;
  4337. }
  4338. }
  4339. internal uint headerSize() {
  4340. // Console.WriteLine(name + " stream has headersize of " + sizeOfHeader);
  4341. return sizeOfHeader;
  4342. }
  4343. internal void SetSize(uint siz) {
  4344. size = siz;
  4345. }
  4346. internal uint Size() {
  4347. return size;
  4348. }
  4349. internal bool LargeIx() {
  4350. return largeIx;
  4351. }
  4352. internal void WriteDetails() {
  4353. // Console.WriteLine(name + " - size = " + size);
  4354. }
  4355. internal uint Add(string str, bool prependSize) {
  4356. Object val = htable[str];
  4357. uint index = 0;
  4358. if (val == null) {
  4359. index = size;
  4360. htable[str] = index;
  4361. char[] arr = str.ToCharArray();
  4362. if (prependSize) CompressNum((uint)arr.Length*2+1);
  4363. Write(arr);
  4364. Write((byte)0);
  4365. size = (uint)Seek(0,SeekOrigin.Current);
  4366. } else {
  4367. index = (uint)val;
  4368. }
  4369. return index;
  4370. }
  4371. internal uint Add (byte[] str, bool prependSize) {
  4372. Object val = btable [str];
  4373. uint index = 0;
  4374. if (val == null) {
  4375. index = size;
  4376. btable [str] = index;
  4377. if (prependSize) CompressNum ((uint) str.Length);
  4378. Write (str);
  4379. size = (uint) Seek (0, SeekOrigin.Current);
  4380. } else {
  4381. index = (uint) val;
  4382. }
  4383. return index;
  4384. }
  4385. internal uint Add(Guid guid, bool prependSize) {
  4386. byte [] b = guid.ToByteArray ();
  4387. if (prependSize) CompressNum ((uint) b.Length);
  4388. Write(guid.ToByteArray());
  4389. size =(uint)Seek(0,SeekOrigin.Current);
  4390. return tide++;
  4391. }
  4392. internal uint Add(byte[] blob) {
  4393. uint ix = size;
  4394. CompressNum((uint)blob.Length);
  4395. Write(blob);
  4396. size = (uint)Seek(0,SeekOrigin.Current);
  4397. return ix;
  4398. }
  4399. internal uint Add(byte val, bool prependSize) {
  4400. uint ix = size;
  4401. if (prependSize) CompressNum (1);
  4402. Write(val);
  4403. size = (uint)Seek(0,SeekOrigin.Current);
  4404. return ix;
  4405. }
  4406. internal uint Add(sbyte val, bool prependSize) {
  4407. uint ix = size;
  4408. if (prependSize) CompressNum (1);
  4409. Write(val);
  4410. size = (uint)Seek(0,SeekOrigin.Current);
  4411. return ix;
  4412. }
  4413. internal uint Add(ushort val, bool prependSize) {
  4414. uint ix = size;
  4415. if (prependSize) CompressNum (2);
  4416. Write(val);
  4417. size = (uint)Seek(0,SeekOrigin.Current);
  4418. return ix;
  4419. }
  4420. internal uint Add(short val, bool prependSize) {
  4421. uint ix = size;
  4422. if (prependSize) CompressNum (2);
  4423. Write(val);
  4424. size = (uint)Seek(0,SeekOrigin.Current);
  4425. return ix;
  4426. }
  4427. internal uint Add(uint val, bool prependSize) {
  4428. uint ix = size;
  4429. if (prependSize) CompressNum (4);
  4430. Write(val);
  4431. size = (uint)Seek(0,SeekOrigin.Current);
  4432. return ix;
  4433. }
  4434. internal uint Add(int val, bool prependSize) {
  4435. uint ix = size;
  4436. if (prependSize) CompressNum (4);
  4437. Write (val);
  4438. size = (uint)Seek(0,SeekOrigin.Current);
  4439. return ix;
  4440. }
  4441. internal uint Add(ulong val, bool prependSize) {
  4442. uint ix = size;
  4443. if (prependSize) CompressNum (8);
  4444. Write(val);
  4445. size = (uint)Seek(0,SeekOrigin.Current);
  4446. return ix;
  4447. }
  4448. internal uint Add(long val, bool prependSize) {
  4449. uint ix = size;
  4450. if (prependSize) CompressNum (8);
  4451. Write(val);
  4452. size = (uint)Seek(0,SeekOrigin.Current);
  4453. return ix;
  4454. }
  4455. internal uint Add(float val, bool prependSize) {
  4456. uint ix = size;
  4457. if (prependSize) CompressNum (4);
  4458. Write(val);
  4459. size = (uint)Seek(0,SeekOrigin.Current);
  4460. return ix;
  4461. }
  4462. internal uint Add(double val, bool prependSize) {
  4463. uint ix = size;
  4464. if (prependSize) CompressNum (8);
  4465. Write(val);
  4466. size = (uint)Seek(0,SeekOrigin.Current);
  4467. return ix;
  4468. }
  4469. private void CompressNum(uint val) {
  4470. if (val < 0x7F) {
  4471. Write((byte)val);
  4472. } else if (val < 0x3FFF) {
  4473. byte b1 = (byte)((val >> 8) | 0x80);
  4474. byte b2 = (byte)(val & FileImage.iByteMask[0]);
  4475. Write(b1);
  4476. Write(b2);
  4477. } else {
  4478. byte b1 = (byte)((val >> 24) | 0xC0);
  4479. byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
  4480. byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
  4481. byte b4 = (byte)(val & FileImage.iByteMask[0]);
  4482. Write(b1);
  4483. Write(b2);
  4484. Write(b3);
  4485. Write(b4);
  4486. }
  4487. }
  4488. private void QuadAlign() {
  4489. if ((size % 4) != 0) {
  4490. uint pad = 4 - (size % 4);
  4491. size += pad;
  4492. for (int i=0; i < pad; i++) {
  4493. Write((byte)0);
  4494. }
  4495. }
  4496. }
  4497. internal void EndStream() {
  4498. QuadAlign();
  4499. if (size > maxSmlIxSize) {
  4500. largeIx = true;
  4501. }
  4502. }
  4503. internal void WriteHeader(BinaryWriter output) {
  4504. output.Write(start);
  4505. output.Write(size);
  4506. output.Write(name);
  4507. }
  4508. internal virtual void Write(BinaryWriter output) {
  4509. // Console.WriteLine("Writing " + name + " stream at " + output.Seek(0,SeekOrigin.Current) + " = " + start);
  4510. MemoryStream str = (MemoryStream)BaseStream;
  4511. output.Write(str.ToArray());
  4512. }
  4513. }
  4514. /**************************************************************************/
  4515. /// <summary>
  4516. /// Base class for Method Descriptors
  4517. /// </summary>
  4518. public abstract class Method : Member
  4519. {
  4520. protected CallConv callConv = CallConv.Default;
  4521. protected Type retType;
  4522. internal Method(string methName, Type rType) : base(methName)
  4523. {
  4524. retType = rType;
  4525. }
  4526. /// <summary>
  4527. /// Add calling conventions to this method descriptor
  4528. /// </summary>
  4529. /// <param name="cconv"></param>
  4530. public void AddCallConv(CallConv cconv) {
  4531. callConv |= cconv;
  4532. }
  4533. internal abstract void TypeSig(MemoryStream sig);
  4534. internal uint GetSigIx(MetaData md) {
  4535. MemoryStream sig = new MemoryStream();
  4536. TypeSig(sig);
  4537. return md.AddToBlobHeap(sig.ToArray());
  4538. }
  4539. internal Type GetRetType() {
  4540. return retType;
  4541. }
  4542. }
  4543. /**************************************************************************/
  4544. /// <summary>
  4545. /// Descriptor for a method defined in THIS assembly/module
  4546. /// IL .method
  4547. /// </summary>
  4548. public class MethodDef : Method
  4549. {
  4550. private static readonly ushort PInvokeImpl = 0x2000;
  4551. //private static readonly uint UnmanagedExport = 0x0008;
  4552. // private static readonly byte LocalSigByte = 0x7;
  4553. uint parIx = 0, textOffset = 0;
  4554. MetaData metaData;
  4555. CILInstructions code;
  4556. ArrayList securityActions = new ArrayList();
  4557. Param[] parList;
  4558. Local[] locals;
  4559. bool initLocals;
  4560. ushort methFlags = 0, implFlags = 0;
  4561. int maxStack = 0, numPars = 0;
  4562. bool entryPoint = false;
  4563. LocalSig localSig;
  4564. ArrayList varArgSigList;
  4565. ImplMap pinvokeImpl;
  4566. internal MethodDef(MetaData md, string name, Type retType, Param[] pars) : base(name,retType) {
  4567. metaData = md;
  4568. parList = pars;
  4569. if (parList != null) numPars = parList.Length;
  4570. tabIx = MDTable.Method;
  4571. }
  4572. internal MethodDef(MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name, Type retType, Param[] pars) : base(name,retType) {
  4573. metaData = md;
  4574. parList = pars;
  4575. if (parList != null) numPars = parList.Length;
  4576. // Console.WriteLine("Creating method " + name + " with " + numPars + " parameters");
  4577. methFlags = (ushort)mAttrSet;
  4578. implFlags = (ushort)iAttrSet;
  4579. tabIx = MDTable.Method;
  4580. }
  4581. internal Param[] GetPars() {
  4582. return parList;
  4583. }
  4584. /// <summary>
  4585. /// Add some attributes to this method descriptor
  4586. /// </summary>
  4587. /// <param name="ma">the attributes to be added</param>
  4588. public void AddMethAttribute(MethAttr ma) {
  4589. methFlags |= (ushort)ma;
  4590. }
  4591. /// <summary>
  4592. /// Add some implementation attributes to this method descriptor
  4593. /// </summary>
  4594. /// <param name="ia">the attributes to be added</param>
  4595. public void AddImplAttribute(ImplAttr ia) {
  4596. implFlags |= (ushort)ia;
  4597. }
  4598. public void AddPInvokeInfo(ModuleRef scope, string methName,
  4599. PInvokeAttr callAttr) {
  4600. pinvokeImpl = new ImplMap((ushort)callAttr,this,methName,scope);
  4601. methFlags |= PInvokeImpl;
  4602. }
  4603. /// <summary>
  4604. /// Add a named generic type parameter
  4605. /// </summary>
  4606. public GenericParameter AddGenericParameter (short index, string name) {
  4607. GenericParameter gp = new GenericParameter (this, metaData, index, name);
  4608. metaData.AddToTable (MDTable.GenericParam, gp);
  4609. return gp;
  4610. }
  4611. /// <summary>
  4612. /// Set the maximum stack height for this method
  4613. /// </summary>
  4614. /// <param name="maxStack">the maximum height of the stack</param>
  4615. public void SetMaxStack(int maxStack) {
  4616. this.maxStack = maxStack;
  4617. }
  4618. /// <summary>
  4619. /// Add local variables to this method
  4620. /// </summary>
  4621. /// <param name="locals">the locals to be added</param>
  4622. /// <param name="initLocals">are locals initialised to default values</param>
  4623. public void AddLocals(Local[] locals, bool initLocals) {
  4624. this.locals = locals;
  4625. this.initLocals = initLocals;
  4626. }
  4627. /// <summary>
  4628. /// Mark this method as having an entry point
  4629. /// </summary>
  4630. public void DeclareEntryPoint() {
  4631. entryPoint = true;
  4632. }
  4633. /// <summary>
  4634. /// Create a code buffer for this method to add the IL instructions to
  4635. /// </summary>
  4636. /// <returns>a buffer for this method's IL instructions</returns>
  4637. public CILInstructions CreateCodeBuffer() {
  4638. code = new CILInstructions(metaData);
  4639. return code;
  4640. }
  4641. /// <summary>
  4642. /// Make a method reference descriptor for this method to be used
  4643. /// as a callsite signature for this vararg method
  4644. /// </summary>
  4645. /// <param name="optPars">the optional pars for the vararg method call</param>
  4646. /// <returns></returns>
  4647. public MethodRef MakeVarArgSignature(Type[] optPars) {
  4648. Type[] pars = new Type[numPars];
  4649. MethodRef varArgSig;
  4650. for (int i=0; i < numPars; i++) {
  4651. pars[i] = parList[i].GetParType();
  4652. }
  4653. varArgSig = new MethodRef(this,name,retType,pars,true,optPars);
  4654. if (varArgSigList == null)
  4655. varArgSigList = new ArrayList ();
  4656. varArgSigList.Add (varArgSig);
  4657. return varArgSig;
  4658. }
  4659. internal sealed override void TypeSig(MemoryStream sig) {
  4660. sig.WriteByte((byte)callConv);
  4661. MetaData.CompressNum((uint)numPars,sig);
  4662. retType.TypeSig(sig);
  4663. for (ushort i=0; i < numPars; i++) {
  4664. parList[i].seqNo = (ushort)(i+1);
  4665. parList[i].TypeSig(sig);
  4666. }
  4667. }
  4668. internal sealed override void BuildTables(MetaData md) {
  4669. if (done) return;
  4670. if (pinvokeImpl != null) {
  4671. md.AddToTable(MDTable.ImplMap,pinvokeImpl);
  4672. pinvokeImpl.BuildTables(md);
  4673. }
  4674. if (entryPoint) md.SetEntryPoint(this);
  4675. uint locToken = 0;
  4676. if (locals != null) {
  4677. localSig = new LocalSig(locals);
  4678. md.AddToTable(MDTable.StandAloneSig,localSig);
  4679. localSig.BuildTables(md);
  4680. locToken = localSig.Token();
  4681. }
  4682. if (code != null) {
  4683. code.CheckCode(locToken,initLocals,maxStack);
  4684. textOffset = md.AddCode(code);
  4685. }
  4686. nameIx = md.AddToStringsHeap(name);
  4687. sigIx = GetSigIx(md);
  4688. parIx = md.TableIndex(MDTable.Param);
  4689. for (int i=0; i < numPars; i++) {
  4690. md.AddToTable(MDTable.Param,parList[i]);
  4691. parList[i].BuildTables(md);
  4692. }
  4693. if (varArgSigList != null) {
  4694. foreach (MethodRef varArgSig in varArgSigList) {
  4695. md.AddToTable(MDTable.MemberRef,varArgSig);
  4696. varArgSig.BuildTables(md);
  4697. }
  4698. }
  4699. // Console.WriteLine("method has " + numPars + " parameters");
  4700. done = true;
  4701. }
  4702. internal sealed override uint Size(MetaData md) {
  4703. return 8 + md.StringsIndexSize() + md.BlobIndexSize() + md.TableIndexSize(MDTable.Param);
  4704. }
  4705. internal sealed override void Write(FileImage output) {
  4706. if (ZeroRva ()) output.Write(0);
  4707. else output.WriteCodeRVA(textOffset);
  4708. output.Write(implFlags);
  4709. output.Write(methFlags);
  4710. output.StringsIndex(nameIx);
  4711. output.BlobIndex(sigIx);
  4712. output.WriteIndex(MDTable.Param,parIx);
  4713. }
  4714. internal bool ZeroRva () {
  4715. return (((methFlags & (ushort)MethAttr.Abstract) != 0) ||
  4716. ((implFlags & (ushort)ImplAttr.Runtime) != 0) ||
  4717. ((implFlags & (ushort)ImplAttr.InternalCall) != 0) ||
  4718. (pinvokeImpl != null)); // TODO: Not entirely true but works for now
  4719. }
  4720. internal sealed override uint GetCodedIx(CIx code) {
  4721. switch (code) {
  4722. case (CIx.HasCustomAttr) : return 0;
  4723. case (CIx.HasDeclSecurity) : return 1;
  4724. case (CIx.MemberRefParent) : return 3;
  4725. case (CIx.MethodDefOrRef) : return 0;
  4726. case (CIx.MemberForwarded) : return 1;
  4727. case (CIx.CustomAttributeType) : return 2;
  4728. case (CIx.TypeOrMethodDef) : return 1;
  4729. }
  4730. return 0;
  4731. }
  4732. }
  4733. /**************************************************************************/
  4734. /// <summary>
  4735. /// Descriptor for an overriding method (.override)
  4736. /// </summary>
  4737. public class MethodImpl : MetaDataElement
  4738. {
  4739. ClassDef parent;
  4740. Method header, body;
  4741. internal MethodImpl(ClassDef par, Method decl, Method bod) {
  4742. parent = par;
  4743. header = decl;
  4744. body = bod;
  4745. tabIx = MDTable.MethodImpl;
  4746. }
  4747. internal sealed override uint Size(MetaData md) {
  4748. return md.TableIndexSize(MDTable.TypeDef) + 2 * md.CodedIndexSize(CIx.MethodDefOrRef);
  4749. }
  4750. internal sealed override void Write(FileImage output) {
  4751. output.WriteIndex(MDTable.TypeDef,parent.Row);
  4752. output.WriteCodedIndex(CIx.MethodDefOrRef,body);
  4753. output.WriteCodedIndex(CIx.MethodDefOrRef,header);
  4754. }
  4755. }
  4756. /**************************************************************************/
  4757. /// <summary>
  4758. /// Descriptor for a method defined in another assembly/module
  4759. /// </summary>
  4760. public class MethodRef : Method
  4761. {
  4762. private static readonly byte Sentinel = 0x41;
  4763. Type[] parList, optParList;
  4764. MetaDataElement parent;
  4765. uint numPars = 0, numOptPars = 0;
  4766. internal MethodRef(MetaDataElement paren, string name, Type retType,
  4767. Type[] pars, bool varArgMeth, Type[] optPars) : base(name,retType) {
  4768. parent = paren;
  4769. parList = pars;
  4770. if (parList != null) numPars = (uint)parList.Length;
  4771. if (varArgMeth) {
  4772. optParList = optPars;
  4773. if (optParList != null) numOptPars = (uint)optParList.Length;
  4774. callConv = CallConv.Vararg;
  4775. }
  4776. }
  4777. internal sealed override void TypeSig(MemoryStream sig) {
  4778. sig.WriteByte((byte)callConv);
  4779. MetaData.CompressNum(numPars+numOptPars,sig);
  4780. retType.TypeSig(sig);
  4781. for (int i=0; i < numPars; i++) {
  4782. parList[i].TypeSig(sig);
  4783. }
  4784. if (numOptPars > 0) {
  4785. sig.WriteByte(Sentinel);
  4786. for (int i=0; i < numOptPars; i++) {
  4787. optParList[i].TypeSig(sig);
  4788. }
  4789. }
  4790. }
  4791. internal sealed override void BuildTables(MetaData md) {
  4792. if (done) return;
  4793. nameIx = md.AddToStringsHeap(name);
  4794. sigIx = GetSigIx(md);
  4795. done = true;
  4796. }
  4797. internal sealed override uint Size(MetaData md) {
  4798. return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
  4799. }
  4800. internal sealed override void Write(FileImage output) {
  4801. output.WriteCodedIndex(CIx.MemberRefParent,parent);
  4802. output.StringsIndex(nameIx);
  4803. output.BlobIndex(sigIx);
  4804. }
  4805. internal sealed override uint GetCodedIx(CIx code) {
  4806. switch (code) {
  4807. case (CIx.HasCustomAttr) : return 6;
  4808. case (CIx.MethodDefOrRef) : return 1;
  4809. case (CIx.CustomAttributeType) : return 3;
  4810. }
  4811. return 0;
  4812. }
  4813. }
  4814. /**************************************************************************/
  4815. /// <summary>
  4816. /// Descriptor for Property and Event methods
  4817. /// </summary>
  4818. public class MethodSemantics : MetaDataElement {
  4819. Feature.MethodType type;
  4820. MethodDef meth;
  4821. Feature eventOrProp;
  4822. internal MethodSemantics(Feature.MethodType mType, MethodDef method, Feature feature) {
  4823. type = mType;
  4824. meth = method;
  4825. eventOrProp = feature;
  4826. tabIx = MDTable.MethodSemantics;
  4827. }
  4828. internal sealed override uint Size(MetaData md) {
  4829. return 2 + md.TableIndexSize(MDTable.Method) + md.CodedIndexSize(CIx.HasSemantics);
  4830. }
  4831. internal sealed override void Write(FileImage output) {
  4832. output.Write((ushort)type);
  4833. output.WriteIndex(MDTable.Method,meth.Row);
  4834. output.WriteCodedIndex(CIx.HasSemantics,eventOrProp);
  4835. }
  4836. }
  4837. /**************************************************************************/
  4838. /// <summary>
  4839. /// Descriptor for a FunctionPointer type
  4840. /// </summary>
  4841. ///
  4842. public class MethPtrType : Type
  4843. {
  4844. bool varArgMeth;
  4845. Type retType;
  4846. Type [] parList;
  4847. Type [] optParList;
  4848. CallConv callConv;
  4849. uint numPars;
  4850. uint numOptPars;
  4851. uint sigIx = 0;
  4852. /// <summary>
  4853. /// Create a new function pointer type
  4854. /// </summary>
  4855. /// <param name="meth">the function to be referenced</param>
  4856. public MethPtrType (CallConv callconv, Type retType, Type[] pars,
  4857. bool varArgMeth, Type[] optPars) : base(0x1B) {
  4858. this.retType = retType;
  4859. callConv = callconv;
  4860. parList = pars;
  4861. this.varArgMeth = varArgMeth;
  4862. if (parList != null) numPars = (uint)parList.Length;
  4863. if (varArgMeth) {
  4864. optParList = optPars;
  4865. if (optParList != null) numOptPars = (uint)optParList.Length;
  4866. callConv |= CallConv.Vararg;
  4867. }
  4868. tabIx = MDTable.TypeSpec;
  4869. }
  4870. internal sealed override void TypeSig(MemoryStream sig) {
  4871. sig.WriteByte(typeIndex);
  4872. // Bootlegged from method ref
  4873. sig.WriteByte((byte)callConv);
  4874. MetaData.CompressNum (numPars + numOptPars, sig);
  4875. retType.TypeSig (sig);
  4876. for (int i=0; i < numPars; i++) {
  4877. parList[i].TypeSig (sig);
  4878. }
  4879. if (varArgMeth) {
  4880. sig.WriteByte (0x41); // Write the sentinel
  4881. for (int i=0; i < numOptPars; i++) {
  4882. optParList[i].TypeSig (sig);
  4883. }
  4884. }
  4885. }
  4886. internal sealed override void BuildTables(MetaData md) {
  4887. if (done) return;
  4888. MemoryStream sig = new MemoryStream();
  4889. TypeSig(sig);
  4890. sigIx = md.AddToBlobHeap(sig.ToArray());
  4891. done = true;
  4892. }
  4893. internal sealed override uint Size(MetaData md) {
  4894. return md.BlobIndexSize();
  4895. }
  4896. internal sealed override void Write(FileImage output) {
  4897. output.BlobIndex(sigIx);
  4898. }
  4899. internal sealed override uint GetCodedIx(CIx code) { return 0x1B; }
  4900. }
  4901. /**************************************************************************/
  4902. /// <summary>
  4903. /// Descriptor for THIS module
  4904. /// </summary>
  4905. public class Module : ResolutionScope
  4906. {
  4907. Guid mvid;
  4908. uint mvidIx = 0;
  4909. internal Module(string name, MetaData md) : base(name,md) {
  4910. mvid = Guid.NewGuid();
  4911. mvidIx = md.AddToGUIDHeap(mvid);
  4912. tabIx = MDTable.Module;
  4913. }
  4914. public Guid Guid {
  4915. get { return mvid; }
  4916. }
  4917. internal sealed override uint Size(MetaData md) {
  4918. return 2 + md.StringsIndexSize() + 3 * md.GUIDIndexSize();
  4919. }
  4920. internal sealed override void Write(FileImage output) {
  4921. output.Write((short)0);
  4922. output.StringsIndex(nameIx);
  4923. output.GUIDIndex(mvidIx);
  4924. output.GUIDIndex(0);
  4925. output.GUIDIndex(0);
  4926. }
  4927. internal sealed override uint GetCodedIx(CIx code) {
  4928. switch (code) {
  4929. case (CIx.HasCustomAttr) : return 7;
  4930. case (CIx.ResolutionScope) : return 0;
  4931. }
  4932. return 0;
  4933. }
  4934. }
  4935. /**************************************************************************/
  4936. /// <summary>
  4937. /// Descriptor for another module in THIS assembly
  4938. /// </summary>
  4939. public class ModuleRef : ResolutionScope, IExternRef
  4940. {
  4941. internal ModuleRef(MetaData md, string name) : base(name,md) {
  4942. tabIx = MDTable.ModuleRef;
  4943. }
  4944. /// <summary>
  4945. /// Add a class to this external module. This is a class declared in
  4946. /// another module of THIS assembly.
  4947. /// </summary>
  4948. /// <param name="nsName">name space name</param>
  4949. /// <param name="name">class name</param>
  4950. /// <returns>a descriptor for this class in another module</returns>
  4951. public ClassRef AddClass(string nsName, string name) {
  4952. ClassRef aClass = new ClassRef(nsName,name,metaData);
  4953. metaData.AddToTable(MDTable.TypeRef,aClass);
  4954. aClass.SetParent(this);
  4955. return aClass;
  4956. }
  4957. /// <summary>
  4958. /// Make a file descriptor to correspond to this module. The file
  4959. /// descriptor will have the same name as the module descriptor
  4960. /// </summary>
  4961. /// <param name="hashBytes">the hash of the file</param>
  4962. /// <param name="hasMetaData">the file contains metadata</param>
  4963. /// <param name="entryPoint">the program entry point is in this file</param>
  4964. /// <returns>a descriptor for the file which contains this module</returns>
  4965. public FileRef MakeFile(byte[] hashBytes, bool hasMetaData, bool entryPoint) {
  4966. FileRef file = new FileRef(nameIx,hashBytes,hasMetaData,entryPoint,metaData);
  4967. metaData.AddToTable(MDTable.File,file);
  4968. return file;
  4969. }
  4970. /// <summary>
  4971. /// Add a value class to this module. This is a class declared in
  4972. /// another module of THIS assembly.
  4973. /// </summary>
  4974. /// <param name="nsName">name space name</param>
  4975. /// <param name="name">class name</param>
  4976. /// <returns></returns>
  4977. public ClassRef AddValueClass(string nsName, string name) {
  4978. ClassRef aClass = new ClassRef(nsName,name,metaData);
  4979. metaData.AddToTable(MDTable.TypeRef,aClass);
  4980. aClass.SetParent(this);
  4981. aClass.MakeValueClass();
  4982. return aClass;
  4983. }
  4984. /// <summary>
  4985. /// Add a class which is declared public in this external module of
  4986. /// THIS assembly. This class will be exported from this assembly.
  4987. /// The ilasm syntax for this is .extern class
  4988. /// </summary>
  4989. /// <param name="attrSet">attributes of the class to be exported</param>
  4990. /// <param name="nsName">name space name</param>
  4991. /// <param name="name">external class name</param>
  4992. /// <param name="declFile">the file where the class is declared</param>
  4993. /// <param name="isValueClass">is this class a value type?</param>
  4994. /// <returns>a descriptor for this external class</returns>
  4995. public ExternClassRef AddExternClass(TypeAttr attrSet, string nsName,
  4996. string name, FileRef declFile,
  4997. bool isValueClass) {
  4998. ExternClassRef cRef = new ExternClassRef(attrSet,nsName,name,declFile,metaData);
  4999. metaData.AddToTable(MDTable.TypeRef,cRef);
  5000. cRef.SetParent(this);
  5001. if (isValueClass) cRef.MakeValueClass();
  5002. return cRef;
  5003. }
  5004. /// <summary>
  5005. /// Add a "global" method in another module
  5006. /// </summary>
  5007. /// <param name="name">method name</param>
  5008. /// <param name="retType">return type</param>
  5009. /// <param name="pars">method parameter types</param>
  5010. /// <returns>a descriptor for this method in anther module</returns>
  5011. public MethodRef AddMethod(string name, Type retType, Type[] pars) {
  5012. MethodRef meth = new MethodRef(this,name,retType,pars,false,null);
  5013. metaData.AddToTable(MDTable.MemberRef,meth);
  5014. return meth;
  5015. }
  5016. /// <summary>
  5017. /// Add a vararg method to this class
  5018. /// </summary>
  5019. /// <param name="name">method name</param>
  5020. /// <param name="retType">return type</param>
  5021. /// <param name="pars">parameter types</param>
  5022. /// <param name="optPars">optional param types for this vararg method</param>
  5023. /// <returns>a descriptor for this method</returns>
  5024. public MethodRef AddVarArgMethod(string name, Type retType,
  5025. Type[] pars, Type[] optPars) {
  5026. MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars);
  5027. metaData.AddToTable(MDTable.MemberRef,meth);
  5028. return meth;
  5029. }
  5030. /// <summary>
  5031. /// Add a field in another module
  5032. /// </summary>
  5033. /// <param name="name">field name</param>
  5034. /// <param name="fType">field type</param>
  5035. /// <returns>a descriptor for this field in another module</returns>
  5036. public FieldRef AddField(string name, Type fType) {
  5037. FieldRef field = new FieldRef(this,name,fType);
  5038. metaData.AddToTable(MDTable.MemberRef,field);
  5039. return field;
  5040. }
  5041. internal sealed override uint Size(MetaData md) {
  5042. return md.StringsIndexSize();
  5043. }
  5044. internal sealed override void Write(FileImage output) {
  5045. output.StringsIndex(nameIx);
  5046. }
  5047. internal sealed override uint GetCodedIx(CIx code) {
  5048. switch (code) {
  5049. case (CIx.HasCustomAttr) : return 12;
  5050. case (CIx.MemberRefParent) : return 2;
  5051. case (CIx.ResolutionScope) : return 1;
  5052. }
  5053. return 0;
  5054. }
  5055. }
  5056. /**************************************************************************/
  5057. /// <summary>
  5058. /// Descriptors for native types used for marshalling
  5059. /// </summary>
  5060. public class NativeType {
  5061. public static readonly NativeType Void = new NativeType(0x01);
  5062. public static readonly NativeType Boolean = new NativeType(0x02);
  5063. public static readonly NativeType Int8 = new NativeType(0x03);
  5064. public static readonly NativeType UInt8 = new NativeType(0x04);
  5065. public static readonly NativeType Int16 = new NativeType(0x05);
  5066. public static readonly NativeType UInt16 = new NativeType(0x06);
  5067. public static readonly NativeType Int32 = new NativeType(0x07);
  5068. public static readonly NativeType UInt32 = new NativeType(0x08);
  5069. public static readonly NativeType Int64 = new NativeType(0x09);
  5070. public static readonly NativeType UInt64 = new NativeType(0x0A);
  5071. public static readonly NativeType Float32 = new NativeType(0x0B);
  5072. public static readonly NativeType Float64 = new NativeType(0x0C);
  5073. public static readonly NativeType Currency = new NativeType(0x0F);
  5074. public static readonly NativeType BStr = new NativeType(0x13);
  5075. public static readonly NativeType LPStr = new NativeType(0x14);
  5076. public static readonly NativeType LPWStr = new NativeType(0x15);
  5077. public static readonly NativeType LPTStr = new NativeType(0x16);
  5078. public static readonly NativeType FixedSysString = new NativeType(0x17);
  5079. public static readonly NativeType IUnknown = new NativeType(0x19);
  5080. public static readonly NativeType IDispatch = new NativeType(0x1A);
  5081. public static readonly NativeType Struct = new NativeType(0x1B);
  5082. public static readonly NativeType Interface = new NativeType(0x1C);
  5083. public static readonly NativeType Int = new NativeType(0x1F);
  5084. public static readonly NativeType UInt = new NativeType(0x20);
  5085. public static readonly NativeType ByValStr = new NativeType(0x22);
  5086. public static readonly NativeType AnsiBStr = new NativeType(0x23);
  5087. public static readonly NativeType TBstr = new NativeType(0x24);
  5088. public static readonly NativeType VariantBool = new NativeType(0x25);
  5089. public static readonly NativeType FuncPtr = new NativeType(0x26);
  5090. public static readonly NativeType AsAny = new NativeType(0x28);
  5091. protected byte typeIndex;
  5092. internal NativeType(byte tyIx) { typeIndex = tyIx; }
  5093. internal byte GetTypeIndex() { return typeIndex; }
  5094. internal virtual byte[] ToBlob() {
  5095. byte[] bytes = new byte[1];
  5096. bytes[0] = GetTypeIndex();
  5097. return bytes;
  5098. }
  5099. }
  5100. public class NativeArray : NativeType
  5101. {
  5102. NativeType elemType;
  5103. uint len = 0, parNum = 0;
  5104. /*
  5105. public NativeArray(NativeType elemType) : base(0x2A) {
  5106. this.elemType = elemType;
  5107. }
  5108. public NativeArray(NativeType elemType, int len) : base(0x2A) {
  5109. this.elemType = elemType;
  5110. this.len = len;
  5111. }
  5112. */
  5113. public NativeArray(NativeType elemType, int numElem, int parNumForLen) : base(0x2A) {
  5114. this.elemType = elemType;
  5115. len = (uint)numElem;
  5116. parNum = (uint)parNumForLen;
  5117. }
  5118. internal override byte[] ToBlob() {
  5119. MemoryStream str = new MemoryStream();
  5120. str.WriteByte(GetTypeIndex());
  5121. if (elemType == null) str.WriteByte(0x50); // no info (MAX)
  5122. else str.WriteByte(elemType.GetTypeIndex());
  5123. MetaData.CompressNum(parNum,str);
  5124. str.WriteByte(1);
  5125. MetaData.CompressNum(len,str);
  5126. return str.ToArray();
  5127. }
  5128. }
  5129. public class SafeArray : NativeType
  5130. {
  5131. SafeArrayType elemType;
  5132. public SafeArray(SafeArrayType elemType) : base(0x1D) {
  5133. this.elemType = elemType;
  5134. }
  5135. internal override byte[] ToBlob() {
  5136. byte[] bytes = new byte[2];
  5137. bytes[0] = GetTypeIndex();
  5138. bytes[1] = (byte)elemType;
  5139. return bytes;
  5140. }
  5141. }
  5142. public class FixedArray : NativeType
  5143. {
  5144. NativeType elemType;
  5145. uint numElem;
  5146. public FixedArray(NativeType elemType, int numElems) : base(0x1E) {
  5147. this.elemType = elemType;
  5148. numElem = (uint)numElems;
  5149. }
  5150. internal override byte[] ToBlob() {
  5151. MemoryStream str = new MemoryStream();
  5152. str.WriteByte(GetTypeIndex());
  5153. MetaData.CompressNum(numElem,str);
  5154. if (elemType == null) str.WriteByte(0x50); // no info (MAX)
  5155. else str.WriteByte(elemType.GetTypeIndex());
  5156. return str.ToArray();
  5157. }
  5158. }
  5159. public class CustomMarshaller : NativeType
  5160. {
  5161. string typeName;
  5162. string marshallerName;
  5163. string cookie;
  5164. public CustomMarshaller(string typeNameOrGUID, string marshallerName,
  5165. string optCookie) : base(0x2C) {
  5166. typeName = typeNameOrGUID;
  5167. this.marshallerName = marshallerName;
  5168. cookie = optCookie;
  5169. }
  5170. internal override byte[] ToBlob() {
  5171. MemoryStream str = new MemoryStream();
  5172. BinaryWriter bw = new BinaryWriter(str,new UTF8Encoding());
  5173. bw.Write(GetTypeIndex());
  5174. bw.Write(typeName.ToCharArray());
  5175. bw.Write((byte)0);
  5176. bw.Write(marshallerName.ToCharArray());
  5177. bw.Write((byte)0);
  5178. if (cookie != null) bw.Write(cookie.ToCharArray());
  5179. bw.Write((byte)0);
  5180. bw.Flush();
  5181. return str.ToArray();
  5182. }
  5183. }
  5184. /**************************************************************************/
  5185. /// <summary>
  5186. /// Descriptor for a parameter of a method defined in this assembly/module
  5187. /// </summary>
  5188. public class Param : MetaDataElement
  5189. {
  5190. private static readonly ushort hasDefault = 0x1000;
  5191. private static readonly ushort hasFieldMarshal = 0x2000;
  5192. Type pType;
  5193. string pName;
  5194. internal ushort seqNo = 0;
  5195. ushort parMode;
  5196. ConstantElem defaultVal;
  5197. uint nameIx = 0;
  5198. FieldMarshal marshalInfo;
  5199. /// <summary>
  5200. /// Create a new parameter for a method
  5201. /// </summary>
  5202. /// <param name="mode">param mode (in, out, opt)</param>
  5203. /// <param name="parName">parameter name</param>
  5204. /// <param name="parType">parameter type</param>
  5205. public Param(ParamAttr mode, string parName, Type parType) {
  5206. pName = parName;
  5207. pType = parType;
  5208. parMode = (ushort)mode;
  5209. tabIx = MDTable.Param;
  5210. }
  5211. /// <summary>
  5212. /// Add a default value to this parameter
  5213. /// </summary>
  5214. /// <param name="c">the default value for the parameter</param>
  5215. public void AddDefaultValue(Constant cVal) {
  5216. defaultVal = new ConstantElem(this,cVal);
  5217. parMode |= hasDefault;
  5218. }
  5219. /// <summary>
  5220. /// Add marshalling information about this parameter
  5221. /// </summary>
  5222. public void AddMarshallInfo(NativeType marshallType) {
  5223. parMode |= hasFieldMarshal;
  5224. marshalInfo = new FieldMarshal(this,marshallType);
  5225. }
  5226. internal Type GetParType() { return pType; }
  5227. internal sealed override void BuildTables(MetaData md) {
  5228. if (done) return;
  5229. nameIx = md.AddToStringsHeap(pName);
  5230. if (defaultVal != null) {
  5231. md.AddToTable(MDTable.Constant,defaultVal);
  5232. defaultVal.BuildTables(md);
  5233. }
  5234. if (marshalInfo != null) {
  5235. md.AddToTable(MDTable.FieldMarshal,marshalInfo);
  5236. marshalInfo.BuildTables(md);
  5237. }
  5238. done = true;
  5239. }
  5240. internal void TypeSig(MemoryStream str) {
  5241. pType.TypeSig(str);
  5242. }
  5243. internal sealed override uint Size(MetaData md) {
  5244. return 4 + md.StringsIndexSize();
  5245. }
  5246. internal sealed override void Write(FileImage output) {
  5247. output.Write(parMode);
  5248. output.Write(seqNo);
  5249. output.StringsIndex(nameIx);
  5250. }
  5251. internal sealed override uint GetCodedIx(CIx code) {
  5252. switch (code) {
  5253. case (CIx.HasCustomAttr) : return 4;
  5254. case (CIx.HasConst) : return 1;
  5255. case (CIx.HasFieldMarshal) : return 1;
  5256. }
  5257. return 0;
  5258. }
  5259. }
  5260. /**************************************************************************/
  5261. /// <summary>
  5262. /// Base class for the PEFile (starting point)
  5263. /// </summary>
  5264. public class PEFile
  5265. {
  5266. private static readonly string mscorlibName = "mscorlib";
  5267. private Module thisMod;
  5268. private ClassDef moduleClass;
  5269. private ArrayList classRefList = new ArrayList();
  5270. private ArrayList classDefList = new ArrayList();
  5271. private Assembly thisAssembly;
  5272. private int corFlags = 1;
  5273. FileImage fileImage;
  5274. MetaData metaData;
  5275. /// <summary>
  5276. /// Create a new PEFile. Each PEFile is a module.
  5277. /// </summary>
  5278. /// <param name="name">module name, also used for the file name</param>
  5279. /// <param name="isDLL">create a .dll or .exe file</param>
  5280. /// <param name="hasAssembly">this file is an assembly and
  5281. /// will contain the assembly manifest. The assembly name is the
  5282. /// same as the module name</param>
  5283. public PEFile(string name, bool isDLL, bool hasAssembly) {
  5284. // Console.WriteLine(Hex.Byte(0x12));
  5285. // Console.WriteLine(Hex.Short(0x1234));
  5286. // Console.WriteLine(Hex.Int(0x12345678));
  5287. string fName = MakeFileName(null,name,isDLL);
  5288. fileImage = new FileImage(isDLL,fName);
  5289. InitPEFile(name, fName, hasAssembly);
  5290. }
  5291. /// <summary>
  5292. /// Create a new PEFile. Each PEFile is a module.
  5293. /// </summary>
  5294. /// <param name="name">module name, also used for the file name</param>
  5295. /// <param name="isDLL">create a .dll or .exe file</param>
  5296. /// <param name="hasAssembly">this file is an assembly and
  5297. /// will contain the assembly manifest. The assembly name is the
  5298. /// same as the module name</param>
  5299. /// <param name="outputDir">write the PEFile to this directory. If this
  5300. /// string is null then the output will be to the current directory</param>
  5301. public PEFile(string name, bool isDLL, bool hasAssembly, string outputDir) {
  5302. // Console.WriteLine(Hex.Byte(0x12));
  5303. // Console.WriteLine(Hex.Short(0x1234));
  5304. // Console.WriteLine(Hex.Int(0x12345678));
  5305. string fName = MakeFileName(outputDir,name,isDLL);
  5306. fileImage = new FileImage(isDLL,fName);
  5307. InitPEFile(name, fName, hasAssembly);
  5308. }
  5309. /// <summary>
  5310. /// Create a new PEFile
  5311. /// </summary>
  5312. /// <param name="name">module name</param>
  5313. /// <param name="isDLL">create a .dll or .exe</param>
  5314. /// <param name="hasAssembly">this PEfile is an assembly and
  5315. /// will contain the assemly manifest. The assembly name is the
  5316. /// same as the module name</param>
  5317. /// <param name="outStream">write the PEFile to this stream instead
  5318. /// of to a new file</param>
  5319. public PEFile(string name, bool isDLL, bool hasAssembly, Stream outStream) {
  5320. fileImage = new FileImage(isDLL,outStream);
  5321. InitPEFile(name, MakeFileName(null,name,isDLL), hasAssembly);
  5322. }
  5323. public PEFile(string name, string module_name, bool isDLL, bool hasAssembly, Stream outStream) {
  5324. fileImage = new FileImage(isDLL,outStream);
  5325. InitPEFile(name, (module_name == null ? MakeFileName(null,name,isDLL) : module_name), hasAssembly);
  5326. }
  5327. private void InitPEFile(string name, string fName, bool hasAssembly) {
  5328. metaData = fileImage.GetMetaData();
  5329. thisMod = new Module(fName,metaData);
  5330. if (hasAssembly) {
  5331. thisAssembly = new Assembly(name,metaData);
  5332. metaData.AddToTable(MDTable.Assembly,thisAssembly);
  5333. }
  5334. moduleClass = AddClass(TypeAttr.Private,"","<Module>");
  5335. moduleClass.SpecialNoSuper();
  5336. metaData.AddToTable(MDTable.Module,thisMod);
  5337. }
  5338. public ClassDef ModuleClass {
  5339. get { return moduleClass; }
  5340. }
  5341. /// <summary>
  5342. /// Set the subsystem (.subsystem) (Default is Windows Console mode)
  5343. /// </summary>
  5344. /// <param name="subS">subsystem value</param>
  5345. public void SetSubSystem(SubSystem subS) {
  5346. fileImage.subSys = subS;
  5347. }
  5348. /// <summary>
  5349. /// Set the flags (.corflags)
  5350. /// </summary>
  5351. /// <param name="flags">the flags value</param>
  5352. public void SetCorFlags(int flags) {
  5353. corFlags = flags;
  5354. }
  5355. private string MakeFileName(string dirName, string name, bool isDLL) {
  5356. string result = "";
  5357. if ((dirName != null) && (dirName.CompareTo("") != 0)) {
  5358. result = dirName;
  5359. if (!dirName.EndsWith("\\")) result += "\\";
  5360. }
  5361. result += name;
  5362. // if (isDLL) result += ".dll"; else result += ".exe";
  5363. return result;
  5364. }
  5365. /// <summary>
  5366. /// Add an external assembly to this PEFile (.assembly extern)
  5367. /// </summary>
  5368. /// <param name="assemName">the external assembly name</param>
  5369. /// <returns>a descriptor for this external assembly</returns>
  5370. public AssemblyRef AddExternAssembly(string assemName) {
  5371. if (assemName.CompareTo(mscorlibName) == 0) return metaData.mscorlib;
  5372. AssemblyRef anAssem = new AssemblyRef(metaData,assemName);
  5373. metaData.AddToTable(MDTable.AssemblyRef,anAssem);
  5374. // Console.WriteLine("Adding assembly " + assemName);
  5375. return anAssem;
  5376. }
  5377. /// <summary>
  5378. /// Add an external module to this PEFile (.module extern)
  5379. /// </summary>
  5380. /// <param name="name">the external module name</param>
  5381. /// <returns>a descriptor for this external module</returns>
  5382. public ModuleRef AddExternModule(string name) {
  5383. ModuleRef modRef = new ModuleRef(metaData,name);
  5384. metaData.AddToTable(MDTable.ModuleRef,modRef);
  5385. return modRef;
  5386. }
  5387. /// <summary>
  5388. /// Add a "global" method to this module
  5389. /// </summary>
  5390. /// <param name="name">method name</param>
  5391. /// <param name="retType">return type</param>
  5392. /// <param name="pars">method parameters</param>
  5393. /// <returns>a descriptor for this new "global" method</returns>
  5394. public MethodDef AddMethod(string name, Type retType, Param[] pars) {
  5395. return moduleClass.AddMethod(name,retType,pars);
  5396. }
  5397. /// <summary>
  5398. /// Add a "global" method to this module
  5399. /// </summary>
  5400. /// <param name="mAtts">method attributes</param>
  5401. /// <param name="iAtts">method implementation attributes</param>
  5402. /// <param name="name">method name</param>
  5403. /// <param name="retType">return type</param>
  5404. /// <param name="pars">method parameters</param>
  5405. /// <returns>a descriptor for this new "global" method</returns>
  5406. public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name, Type retType, Param[] pars) {
  5407. return moduleClass.AddMethod(mAtts,iAtts,name,retType,pars);
  5408. }
  5409. public MethodRef AddMethodToTypeSpec (Type item, string name, Type retType, Type[] pars) {
  5410. MethodRef meth = new MethodRef (item.GetTypeSpec (metaData), name, retType, pars, false, null);
  5411. metaData.AddToTable (MDTable.MemberRef,meth);
  5412. return meth;
  5413. }
  5414. public MethodRef AddVarArgMethodToTypeSpec (Type item, string name, Type retType,
  5415. Type[] pars, Type[] optPars) {
  5416. MethodRef meth = new MethodRef(item.GetTypeSpec (metaData), name,retType,pars,true,optPars);
  5417. metaData.AddToTable(MDTable.MemberRef,meth);
  5418. return meth;
  5419. }
  5420. public FieldRef AddFieldToTypeSpec (Type item, string name, Type fType) {
  5421. FieldRef field = new FieldRef (item.GetTypeSpec (metaData), name,fType);
  5422. metaData.AddToTable (MDTable.MemberRef,field);
  5423. return field;
  5424. }
  5425. public void AddMethodSpec (Method m, GenericMethodSig g_sig)
  5426. {
  5427. MethodSpec ms = new MethodSpec (m, g_sig);
  5428. metaData.AddToTable (MDTable.MethodSpec, ms);
  5429. }
  5430. /// <summary>
  5431. /// Add a "global" field to this module
  5432. /// </summary>
  5433. /// <param name="name">field name</param>
  5434. /// <param name="fType">field type</param>
  5435. /// <returns>a descriptor for this new "global" field</returns>
  5436. public FieldDef AddField(string name, Type fType) {
  5437. return moduleClass.AddField(name,fType);
  5438. }
  5439. /// <summary>
  5440. /// Add a "global" field to this module
  5441. /// </summary>
  5442. /// <param name="attrSet">attributes of this field</param>
  5443. /// <param name="name">field name</param>
  5444. /// <param name="fType">field type</param>
  5445. /// <returns>a descriptor for this new "global" field</returns>
  5446. public FieldDef AddField(FieldAttr attrSet, string name, Type fType) {
  5447. return moduleClass.AddField(attrSet,name,fType);
  5448. }
  5449. /// <summary>
  5450. /// Add a class to this module
  5451. /// </summary>
  5452. /// <param name="attrSet">attributes of this class</param>
  5453. /// <param name="nsName">name space name</param>
  5454. /// <param name="name">class name</param>
  5455. /// <returns>a descriptor for this new class</returns>
  5456. public ClassDef AddClass(TypeAttr attrSet, string nsName, string name) {
  5457. ClassDef aClass = new ClassDef(attrSet,nsName,name,metaData);
  5458. metaData.AddToTable(MDTable.TypeDef,aClass);
  5459. return aClass;
  5460. }
  5461. /// <summary>
  5462. /// Add a class which extends System.ValueType to this module
  5463. /// </summary>
  5464. /// <param name="attrSet">attributes of this class</param>
  5465. /// <param name="nsName">name space name</param>
  5466. /// <param name="name">class name</param>
  5467. /// <returns>a descriptor for this new class</returns>
  5468. public ClassDef AddValueClass(TypeAttr attrSet, string nsName, string name) {
  5469. ClassDef aClass = new ClassDef(attrSet,nsName,name,metaData);
  5470. aClass.MakeValueClass();
  5471. metaData.AddToTable(MDTable.TypeDef,aClass);
  5472. return aClass;
  5473. }
  5474. /// <summary>
  5475. /// Add a class to this module
  5476. /// </summary>
  5477. /// <param name="attrSet">attributes of this class</param>
  5478. /// <param name="nsName">name space name</param>
  5479. /// <param name="name">class name</param>
  5480. /// <param name="superType">super type of this class (extends)</param>
  5481. /// <returns>a descriptor for this new class</returns>
  5482. public ClassDef AddClass(TypeAttr attrSet, string nsName, string name, Class superType) {
  5483. ClassDef aClass = new ClassDef(attrSet,nsName,name,metaData);
  5484. aClass.SetSuper(superType);
  5485. metaData.AddToTable(MDTable.TypeDef,aClass);
  5486. return aClass;
  5487. }
  5488. public FileRef AddFile(string fName, byte[] hashBytes, bool hasMetaData, bool entryPoint) {
  5489. FileRef file = new FileRef(fName,hashBytes,hasMetaData,entryPoint,metaData);
  5490. metaData.AddToTable(MDTable.File,file);
  5491. return file;
  5492. }
  5493. /// <summary>
  5494. /// Add a manifest resource to this PEFile NOT YET IMPLEMENTED
  5495. /// </summary>
  5496. /// <param name="mr"></param>
  5497. public void AddManifestResource(ManifestResource mr) {
  5498. metaData.AddToTable(MDTable.ManifestResource,mr);
  5499. //mr.FixName(metaData);
  5500. }
  5501. public void AddCustomAttribute (Method meth, byte [] data, MetaDataElement element)
  5502. {
  5503. metaData.AddCustomAttribute (new CustomAttribute (element, meth, data));
  5504. }
  5505. /// <summary>
  5506. /// Write out the PEFile (the "bake" function)
  5507. /// </summary>
  5508. public void WritePEFile() { /* the "bake" function */
  5509. fileImage.ReserveStrongNameSignatureSpace = thisAssembly.HasPublicKey;
  5510. fileImage.MakeFile();
  5511. }
  5512. /// <summary>
  5513. /// Get the descriptor of this module
  5514. /// </summary>
  5515. /// <returns>the descriptor for this module</returns>
  5516. public Module GetThisModule() {
  5517. return thisMod;
  5518. }
  5519. /// <summary>
  5520. /// Get the descriptor for this assembly. The PEFile must have been
  5521. /// created with hasAssembly = true
  5522. /// </summary>
  5523. /// <returns>the descriptor for this assembly</returns>
  5524. public Assembly GetThisAssembly() {
  5525. return thisAssembly;
  5526. }
  5527. }
  5528. /**************************************************************************/
  5529. /// <summary>
  5530. /// Descriptor for the Primitive types defined in IL
  5531. /// </summary>
  5532. public class PrimitiveType : Type
  5533. {
  5534. private string name;
  5535. private int systemTypeIndex;
  5536. public static int NumSystemTypes = 18;
  5537. public static readonly PrimitiveType Void = new PrimitiveType(0x01,"Void",0);
  5538. public static readonly PrimitiveType Boolean = new PrimitiveType(0x02,"Boolean",1);
  5539. public static readonly PrimitiveType Char = new PrimitiveType(0x03,"Char",2);
  5540. public static readonly PrimitiveType Int8 = new PrimitiveType(0x04,"SByte",3);
  5541. public static readonly PrimitiveType UInt8 = new PrimitiveType(0x05,"Byte",4);
  5542. public static readonly PrimitiveType Int16 = new PrimitiveType(0x06,"Int16",5);
  5543. public static readonly PrimitiveType UInt16 = new PrimitiveType(0x07,"UInt16",6);
  5544. public static readonly PrimitiveType Int32 = new PrimitiveType(0x08,"Int32",7);
  5545. public static readonly PrimitiveType UInt32 = new PrimitiveType(0x09,"UInt32",8);
  5546. public static readonly PrimitiveType Int64 = new PrimitiveType(0x0A,"Int64",9);
  5547. public static readonly PrimitiveType UInt64 = new PrimitiveType(0x0B,"UInt64",10);
  5548. public static readonly PrimitiveType Float32 = new PrimitiveType(0x0C,"Single",11);
  5549. public static readonly PrimitiveType Float64 = new PrimitiveType(0x0D,"Double",12);
  5550. public static readonly PrimitiveType String = new PrimitiveType(0x0E,"String",13);
  5551. internal static readonly PrimitiveType Class = new PrimitiveType(0x12);
  5552. public static readonly PrimitiveType TypedRef = new PrimitiveType(0x16,"TypedReference",14);
  5553. public static readonly PrimitiveType IntPtr = new PrimitiveType(0x18,"IntPtr",15);
  5554. public static readonly PrimitiveType UIntPtr = new PrimitiveType(0x19,"UIntPtr",16);
  5555. public static readonly PrimitiveType Object = new PrimitiveType(0x1C,"Object",17);
  5556. internal static readonly PrimitiveType ClassType = new PrimitiveType(0x50);
  5557. public static readonly PrimitiveType NativeInt = IntPtr;
  5558. public static readonly PrimitiveType NativeUInt = UIntPtr;
  5559. internal PrimitiveType(byte typeIx) : base(typeIx) { }
  5560. internal PrimitiveType(byte typeIx, string name, int STIx) : base(typeIx) {
  5561. this.name = name;
  5562. this.systemTypeIndex = STIx;
  5563. }
  5564. internal string GetName() { return name; }
  5565. internal int GetSystemTypeIx() { return systemTypeIndex; }
  5566. internal sealed override void TypeSig(MemoryStream str) {
  5567. str.WriteByte(typeIndex);
  5568. }
  5569. internal override MetaDataElement GetTypeSpec(MetaData md) {
  5570. TypeSpec tS = md.GetPrimitiveTypeSpec(systemTypeIndex);
  5571. if (tS == null) {
  5572. tS = new TypeSpec(this,md);
  5573. md.SetPrimitiveTypeSpec(systemTypeIndex,tS);
  5574. md.AddToTable(MDTable.TypeSpec,tS);
  5575. }
  5576. return tS;
  5577. }
  5578. }
  5579. /**************************************************************************/
  5580. /// <summary>
  5581. /// Descriptor for the Property of a class
  5582. /// </summary>
  5583. public class Property : Feature
  5584. {
  5585. private static readonly byte PropertyTag = 0x8;
  5586. MethodDef getterMeth;
  5587. ConstantElem constVal;
  5588. uint typeBlobIx = 0;
  5589. Type[] parList;
  5590. Type returnType;
  5591. uint numPars = 0;
  5592. internal Property(string name, Type retType, Type[] pars, ClassDef parent) : base(name, parent) {
  5593. returnType = retType;
  5594. parList = pars;
  5595. if (pars != null) numPars = (uint)pars.Length;
  5596. tabIx = MDTable.Property;
  5597. }
  5598. /// <summary>
  5599. /// Add a set method to this property
  5600. /// </summary>
  5601. /// <param name="setter">the set method</param>
  5602. public void AddSetter(MethodDef setter) {
  5603. AddMethod(setter,MethodType.Setter);
  5604. }
  5605. /// <summary>
  5606. /// Add a get method to this property
  5607. /// </summary>
  5608. /// <param name="getter">the get method</param>
  5609. public void AddGetter(MethodDef getter) {
  5610. AddMethod(getter,MethodType.Getter);
  5611. getterMeth = getter;
  5612. }
  5613. /// <summary>
  5614. /// Add another method to this property
  5615. /// </summary>
  5616. /// <param name="other">the method</param>
  5617. public void AddOther(MethodDef other) {
  5618. AddMethod(other,MethodType.Other);
  5619. }
  5620. /// <summary>
  5621. /// Add an initial value for this property
  5622. /// </summary>
  5623. /// <param name="constVal">the initial value for this property</param>
  5624. public void AddInitValue(Constant constVal) {
  5625. this.constVal = new ConstantElem(this,constVal);
  5626. }
  5627. internal sealed override void BuildTables(MetaData md) {
  5628. if (done) return;
  5629. nameIx = md.AddToStringsHeap(name);
  5630. MemoryStream sig = new MemoryStream();
  5631. sig.WriteByte(PropertyTag);
  5632. MetaData.CompressNum(numPars,sig);
  5633. returnType.TypeSig(sig);
  5634. for (int i=0; i < numPars; i++) {
  5635. parList[i].TypeSig(sig);
  5636. }
  5637. typeBlobIx = md.AddToBlobHeap(sig.ToArray());
  5638. for (int i=0; i < tide; i++) {
  5639. md.AddToTable(MDTable.MethodSemantics,methods[i]);
  5640. }
  5641. if (constVal != null) {
  5642. md.AddToTable(MDTable.Constant,constVal);
  5643. constVal.BuildTables(md);
  5644. }
  5645. done = true;
  5646. }
  5647. internal sealed override uint Size(MetaData md) {
  5648. return 2 + md.StringsIndexSize() + md.BlobIndexSize();
  5649. }
  5650. internal sealed override void Write(FileImage output) {
  5651. output.Write(flags);
  5652. output.StringsIndex(nameIx);
  5653. output.BlobIndex(typeBlobIx);
  5654. }
  5655. internal sealed override uint GetCodedIx(CIx code) {
  5656. switch (code) {
  5657. case (CIx.HasCustomAttr) : return 9;
  5658. case (CIx.HasConst) : return 2;
  5659. case (CIx.HasSemantics) : return 1;
  5660. }
  5661. return 0;
  5662. }
  5663. }
  5664. /**************************************************************************/
  5665. /// <summary>
  5666. /// Descriptor for an pointer (type * or type &)
  5667. /// </summary>
  5668. public abstract class PtrType : Type
  5669. {
  5670. Type baseType;
  5671. internal PtrType(Type bType, byte typeIx) : base(typeIx)
  5672. {
  5673. baseType = bType;
  5674. tabIx = MDTable.TypeSpec;
  5675. }
  5676. internal sealed override void TypeSig(MemoryStream str) {
  5677. str.WriteByte(typeIndex);
  5678. baseType.TypeSig(str);
  5679. }
  5680. }
  5681. /**************************************************************************/
  5682. /// <summary>
  5683. /// Descriptor for a managed pointer (type & or byref)
  5684. /// </summary>
  5685. public class ManagedPointer : PtrType // <type> & (BYREF)
  5686. {
  5687. /// <summary>
  5688. /// Create new managed pointer to baseType
  5689. /// </summary>
  5690. /// <param name="bType">the base type of the pointer</param>
  5691. public ManagedPointer(Type baseType) : base(baseType,0x10) { }
  5692. }
  5693. /**************************************************************************/
  5694. /// <summary>
  5695. /// Descriptor for an unmanaged pointer (type *)
  5696. /// </summary>
  5697. public class UnmanagedPointer : PtrType // PTR
  5698. {
  5699. /// <summary>
  5700. /// Create a new unmanaged pointer to baseType
  5701. /// </summary>
  5702. /// <param name="baseType">the base type of the pointer</param>
  5703. public UnmanagedPointer(Type baseType) : base(baseType, 0x0F) { }
  5704. }
  5705. /**************************************************************************/
  5706. /// <summary>
  5707. /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)
  5708. /// </summary>
  5709. public abstract class ResolutionScope : MetaDataElement
  5710. {
  5711. protected uint nameIx = 0;
  5712. protected MetaData metaData;
  5713. protected string name;
  5714. internal ResolutionScope(string name, MetaData md)
  5715. {
  5716. metaData = md;
  5717. this.name = name;
  5718. nameIx = md.AddToStringsHeap(name);
  5719. }
  5720. internal string GetName() { return name; }
  5721. }
  5722. /**************************************************************************/
  5723. /// <summary>
  5724. /// Descriptor for a Section in a PEFile eg .text, .sdata
  5725. /// </summary>
  5726. internal class Section {
  5727. private static readonly uint relocPageSize = 4096; // 4K pages for fixups
  5728. char[] name;
  5729. uint offset = 0, tide = 0, size = 0, rva = 0, relocTide = 0;
  5730. //uint relocOff = 0;
  5731. uint flags = 0, padding = 0;
  5732. uint[] relocs;
  5733. internal Section(string sName, uint sFlags) {
  5734. name = sName.ToCharArray();
  5735. flags = sFlags;
  5736. }
  5737. internal uint Tide() { return tide; }
  5738. internal void IncTide(uint incVal) { tide += incVal; }
  5739. internal uint Padding() { return padding; }
  5740. internal uint Size() { return size; }
  5741. internal void SetSize(uint pad) {
  5742. padding = pad;
  5743. size = tide + padding;
  5744. }
  5745. internal uint RVA() { return rva; }
  5746. internal void SetRVA(uint rva) { this.rva = rva; }
  5747. internal uint Offset() { return offset; }
  5748. internal void SetOffset(uint offs) { offset = offs; }
  5749. internal void DoBlock(BinaryWriter reloc, uint page, int start, int end) {
  5750. //Console.WriteLine("rva = " + rva + " page = " + page);
  5751. reloc.Write(rva + page);
  5752. reloc.Write((uint)(((end-start+1)*2) + 8));
  5753. for (int j=start; j < end; j++) {
  5754. //Console.WriteLine("reloc offset = " + relocs[j]);
  5755. reloc.Write((ushort)((0x3 << 12) | (relocs[j] - page)));
  5756. }
  5757. reloc.Write((ushort)0);
  5758. }
  5759. internal void DoRelocs(BinaryWriter reloc) {
  5760. if (relocTide > 0) {
  5761. //relocOff = (uint)reloc.Seek(0,SeekOrigin.Current);
  5762. uint block = (relocs[0]/relocPageSize + 1) * relocPageSize;
  5763. int start = 0;
  5764. for (int i=1; i < relocTide; i++) {
  5765. if (relocs[i] >= block) {
  5766. DoBlock(reloc,block-relocPageSize,start,i);
  5767. start = i;
  5768. block = (relocs[i]/relocPageSize + 1) * relocPageSize;
  5769. }
  5770. }
  5771. DoBlock(reloc,block-relocPageSize,start,(int)relocTide);
  5772. }
  5773. }
  5774. internal void AddReloc(uint offs) {
  5775. int pos = 0;
  5776. if (relocs == null) {
  5777. relocs = new uint[5];
  5778. } else {
  5779. if (relocTide >= relocs.Length) {
  5780. uint[] tmp = relocs;
  5781. relocs = new uint[tmp.Length + 5];
  5782. for (int i=0; i < relocTide; i++) {
  5783. relocs[i] = tmp[i];
  5784. }
  5785. }
  5786. while ((pos < relocTide) && (relocs[pos] < offs)) pos++;
  5787. for (int i=pos; i < relocTide; i++) {
  5788. relocs[i+1] = relocs[i];
  5789. }
  5790. }
  5791. relocs[pos] = offs;
  5792. relocTide++;
  5793. }
  5794. internal void WriteHeader(BinaryWriter output, uint relocRVA) {
  5795. output.Write(name);
  5796. output.Write(tide);
  5797. output.Write(rva);
  5798. output.Write(size);
  5799. output.Write(offset);
  5800. output.Write(0);
  5801. //output.Write(relocRVA + relocOff);
  5802. output.Write(0);
  5803. output.Write(0);
  5804. //output.Write((ushort)relocTide);
  5805. //output.Write((ushort)0);
  5806. output.Write(flags);
  5807. }
  5808. }
  5809. /**************************************************************************/
  5810. public abstract class Signature : MetaDataElement
  5811. {
  5812. protected uint sigIx;
  5813. internal Signature() {
  5814. tabIx = MDTable.StandAloneSig;
  5815. }
  5816. internal sealed override uint Size(MetaData md) {
  5817. return md.BlobIndexSize();
  5818. }
  5819. internal sealed override void Write(FileImage output) {
  5820. output.BlobIndex(sigIx);
  5821. }
  5822. internal sealed override uint GetCodedIx(CIx code) { return (uint)tabIx; }
  5823. }
  5824. /**************************************************************************/
  5825. /// <summary>
  5826. /// Descriptor for a class defined in System (mscorlib)
  5827. /// </summary>
  5828. internal class SystemClass : ClassRef
  5829. {
  5830. PrimitiveType elemType;
  5831. internal SystemClass(PrimitiveType eType, AssemblyRef paren, MetaData md)
  5832. : base("System",eType.GetName(),md) {
  5833. elemType = eType;
  5834. parent = paren;
  5835. }
  5836. internal override sealed MetaDataElement GetTypeSpec(MetaData md) {
  5837. if (typeSpec == null) typeSpec = (TypeSpec)elemType.GetTypeSpec(md);
  5838. return typeSpec;
  5839. }
  5840. internal sealed override void TypeSig(MemoryStream str) {
  5841. str.WriteByte(elemType.GetTypeIndex());
  5842. }
  5843. }
  5844. /**************************************************************************/
  5845. /// <summary>
  5846. /// Base class for all IL types
  5847. /// </summary>
  5848. public abstract class Type : MetaDataElement {
  5849. protected byte typeIndex;
  5850. protected TypeSpec typeSpec;
  5851. internal Type(byte tyIx) { typeIndex = tyIx; }
  5852. internal byte GetTypeIndex() { return typeIndex; }
  5853. internal void SetTypeIndex (byte b) { typeIndex = b; }
  5854. internal virtual MetaDataElement GetTypeSpec(MetaData md) {
  5855. if (typeSpec == null) {
  5856. typeSpec = new TypeSpec(this,md);
  5857. md.AddToTable(MDTable.TypeSpec,typeSpec);
  5858. }
  5859. return typeSpec;
  5860. }
  5861. internal virtual void TypeSig(MemoryStream str) {
  5862. throw(new TypeSignatureException(this.GetType().AssemblyQualifiedName +
  5863. " doesn't have a type signature!!"));
  5864. }
  5865. }
  5866. /**************************************************************************/
  5867. public class TypeSpec : MetaDataElement {
  5868. uint sigIx = 0;
  5869. internal TypeSpec(Type aType, MetaData md) {
  5870. MemoryStream sig = new MemoryStream();
  5871. aType.TypeSig(sig);
  5872. sigIx = md.AddToBlobHeap(sig.ToArray());
  5873. tabIx = MDTable.TypeSpec;
  5874. }
  5875. internal sealed override uint GetCodedIx(CIx code) {
  5876. switch (code) {
  5877. case (CIx.TypeDefOrRef) : return 2;
  5878. case (CIx.HasCustomAttr) : return 13;
  5879. case (CIx.MemberRefParent) : return 4;
  5880. }
  5881. return 0;
  5882. }
  5883. internal override uint Size(MetaData md) {
  5884. return md.BlobIndexSize();
  5885. }
  5886. internal sealed override void Write(FileImage output) {
  5887. //Console.WriteLine("Writing the blob index for a TypeSpec");
  5888. output.BlobIndex(sigIx);
  5889. }
  5890. }
  5891. class ByteArrayComparer : IComparer {
  5892. public int Compare (object x, object y)
  5893. {
  5894. byte [] a = (byte []) x;
  5895. byte [] b = (byte []) y;
  5896. int len = a.Length;
  5897. if (b.Length != len)
  5898. return 1;
  5899. for (int i = 0; i < len; ++i)
  5900. if (a [i] != b [i])
  5901. return 1;
  5902. return 0;
  5903. }
  5904. }
  5905. class ByteArrayHashCodeProvider : IHashCodeProvider {
  5906. public int GetHashCode (Object key)
  5907. {
  5908. byte [] arr = (byte []) key;
  5909. int len = arr.Length;
  5910. int h = 0;
  5911. for (int i = 0; i < len; ++i)
  5912. h = (h << 5) - h + arr [i];
  5913. return h;
  5914. }
  5915. }
  5916. }