PEAPI.cs 230 KB

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