PEAPI.cs 234 KB

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