| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317 |
- //
- // Author:
- // Jb Evain (jbevain@gmail.com)
- //
- // Copyright (c) 2008 - 2015 Jb Evain
- // Copyright (c) 2008 - 2011 Novell, Inc.
- //
- // Licensed under the MIT/X11 license.
- //
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.IO.Compression;
- using System.Text;
- using Mono;
- using Mono.Collections.Generic;
- using Mono.Cecil.Cil;
- using Mono.Cecil.Metadata;
- using Mono.Cecil.PE;
- using RVA = System.UInt32;
- using RID = System.UInt32;
- using CodedRID = System.UInt32;
- using StringIndex = System.UInt32;
- using BlobIndex = System.UInt32;
- using GuidIndex = System.UInt32;
- namespace Mono.Cecil {
- #if !READ_ONLY
- using ModuleRow = Row<StringIndex, GuidIndex>;
- using TypeRefRow = Row<CodedRID, StringIndex, StringIndex>;
- using TypeDefRow = Row<TypeAttributes, StringIndex, StringIndex, CodedRID, RID, RID>;
- using FieldRow = Row<FieldAttributes, StringIndex, BlobIndex>;
- using MethodRow = Row<RVA, MethodImplAttributes, MethodAttributes, StringIndex, BlobIndex, RID>;
- using ParamRow = Row<ParameterAttributes, ushort, StringIndex>;
- using InterfaceImplRow = Row<uint, CodedRID>;
- using MemberRefRow = Row<CodedRID, StringIndex, BlobIndex>;
- using ConstantRow = Row<ElementType, CodedRID, BlobIndex>;
- using CustomAttributeRow = Row<CodedRID, CodedRID, BlobIndex>;
- using FieldMarshalRow = Row<CodedRID, BlobIndex>;
- using DeclSecurityRow = Row<SecurityAction, CodedRID, BlobIndex>;
- using ClassLayoutRow = Row<ushort, uint, RID>;
- using FieldLayoutRow = Row<uint, RID>;
- using EventMapRow = Row<RID, RID>;
- using EventRow = Row<EventAttributes, StringIndex, CodedRID>;
- using PropertyMapRow = Row<RID, RID>;
- using PropertyRow = Row<PropertyAttributes, StringIndex, BlobIndex>;
- using MethodSemanticsRow = Row<MethodSemanticsAttributes, RID, CodedRID>;
- using MethodImplRow = Row<RID, CodedRID, CodedRID>;
- using ImplMapRow = Row<PInvokeAttributes, CodedRID, StringIndex, RID>;
- using FieldRVARow = Row<RVA, RID>;
- using AssemblyRow = Row<AssemblyHashAlgorithm, ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint>;
- using AssemblyRefRow = Row<ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint, uint>;
- using FileRow = Row<FileAttributes, StringIndex, BlobIndex>;
- using ExportedTypeRow = Row<TypeAttributes, uint, StringIndex, StringIndex, CodedRID>;
- using ManifestResourceRow = Row<uint, ManifestResourceAttributes, StringIndex, CodedRID>;
- using NestedClassRow = Row<RID, RID>;
- using GenericParamRow = Row<ushort, GenericParameterAttributes, CodedRID, StringIndex>;
- using MethodSpecRow = Row<CodedRID, BlobIndex>;
- using GenericParamConstraintRow = Row<RID, CodedRID>;
- using DocumentRow = Row<BlobIndex, GuidIndex, BlobIndex, GuidIndex>;
- using MethodDebugInformationRow = Row<RID, BlobIndex>;
- using LocalScopeRow = Row<RID, RID, RID, RID, uint, uint>;
- using LocalVariableRow = Row<VariableAttributes, ushort, StringIndex>;
- using LocalConstantRow = Row<StringIndex, BlobIndex>;
- using ImportScopeRow = Row<RID, BlobIndex>;
- using StateMachineMethodRow = Row<RID, RID>;
- using CustomDebugInformationRow = Row<CodedRID, GuidIndex, BlobIndex>;
- static class ModuleWriter {
- public static void WriteModule (ModuleDefinition module, Disposable<Stream> stream, WriterParameters parameters)
- {
- using (stream)
- Write (module, stream, parameters);
- }
- static void Write (ModuleDefinition module, Disposable<Stream> stream, WriterParameters parameters)
- {
- if ((module.Attributes & ModuleAttributes.ILOnly) == 0)
- throw new NotSupportedException ("Writing mixed-mode assemblies is not supported");
- if (module.HasImage && module.ReadingMode == ReadingMode.Deferred) {
- var immediate_reader = new ImmediateModuleReader (module.Image);
- immediate_reader.ReadModule (module, resolve_attributes: false);
- immediate_reader.ReadSymbols (module);
- }
- module.MetadataSystem.Clear ();
- if (module.symbol_reader != null)
- module.symbol_reader.Dispose ();
- var name = module.assembly != null ? module.assembly.Name : null;
- var fq_name = stream.value.GetFileName ();
- var timestamp = parameters.Timestamp ?? module.timestamp;
- var symbol_writer_provider = parameters.SymbolWriterProvider;
- if (symbol_writer_provider == null && parameters.WriteSymbols)
- symbol_writer_provider = new DefaultSymbolWriterProvider ();
- #if !NET_CORE
- if (parameters.StrongNameKeyPair != null && name != null) {
- name.PublicKey = parameters.StrongNameKeyPair.PublicKey;
- module.Attributes |= ModuleAttributes.StrongNameSigned;
- }
- #endif
- using (var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider, parameters)) {
- var metadata = new MetadataBuilder (module, fq_name, timestamp, symbol_writer_provider, symbol_writer);
- BuildMetadata (module, metadata);
- var writer = ImageWriter.CreateWriter (module, metadata, stream);
- stream.value.SetLength (0);
- writer.WriteImage ();
- #if !NET_CORE
- if (parameters.StrongNameKeyPair != null)
- CryptoService.StrongName (stream.value, writer, parameters.StrongNameKeyPair);
- #endif
- }
- }
- static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata)
- {
- if (!module.HasImage) {
- metadata.BuildMetadata ();
- return;
- }
- module.Read (metadata, (builder, _) => {
- builder.BuildMetadata ();
- return builder;
- });
- }
- static ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider, WriterParameters parameters)
- {
- if (symbol_writer_provider == null)
- return null;
- if (parameters.SymbolStream != null)
- return symbol_writer_provider.GetSymbolWriter (module, parameters.SymbolStream);
- return symbol_writer_provider.GetSymbolWriter (module, fq_name);
- }
- }
- abstract class MetadataTable {
- public abstract int Length { get; }
- public bool IsLarge {
- get { return Length > ushort.MaxValue; }
- }
- public abstract void Write (TableHeapBuffer buffer);
- public abstract void Sort ();
- }
- abstract class OneRowTable<TRow> : MetadataTable where TRow : struct {
- internal TRow row;
- public sealed override int Length {
- get { return 1; }
- }
- public sealed override void Sort ()
- {
- }
- }
- abstract class MetadataTable<TRow> : MetadataTable where TRow : struct {
- internal TRow [] rows = new TRow [2];
- internal int length;
- public sealed override int Length {
- get { return length; }
- }
- public int AddRow (TRow row)
- {
- if (rows.Length == length)
- Grow ();
- rows [length++] = row;
- return length;
- }
- void Grow ()
- {
- var rows = new TRow [this.rows.Length * 2];
- Array.Copy (this.rows, rows, this.rows.Length);
- this.rows = rows;
- }
- public override void Sort ()
- {
- }
- }
- abstract class SortedTable<TRow> : MetadataTable<TRow>, IComparer<TRow> where TRow : struct {
- public sealed override void Sort ()
- {
- Array.Sort (rows, 0, length, this);
- }
- protected int Compare (uint x, uint y)
- {
- return x == y ? 0 : x > y ? 1 : -1;
- }
- public abstract int Compare (TRow x, TRow y);
- }
- sealed class ModuleTable : OneRowTable<ModuleRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- buffer.WriteUInt16 (0); // Generation
- buffer.WriteString (row.Col1); // Name
- buffer.WriteGuid (row.Col2); // Mvid
- buffer.WriteUInt16 (0); // EncId
- buffer.WriteUInt16 (0); // EncBaseId
- }
- }
- sealed class TypeRefTable : MetadataTable<TypeRefRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (
- rows [i].Col1, CodedIndex.ResolutionScope); // Scope
- buffer.WriteString (rows [i].Col2); // Name
- buffer.WriteString (rows [i].Col3); // Namespace
- }
- }
- }
- sealed class TypeDefTable : MetadataTable<TypeDefRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 ((uint) rows [i].Col1); // Attributes
- buffer.WriteString (rows [i].Col2); // Name
- buffer.WriteString (rows [i].Col3); // Namespace
- buffer.WriteCodedRID (
- rows [i].Col4, CodedIndex.TypeDefOrRef); // Extends
- buffer.WriteRID (rows [i].Col5, Table.Field); // FieldList
- buffer.WriteRID (rows [i].Col6, Table.Method); // MethodList
- }
- }
- }
- sealed class FieldTable : MetadataTable<FieldRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
- buffer.WriteString (rows [i].Col2); // Name
- buffer.WriteBlob (rows [i].Col3); // Signature
- }
- }
- }
- sealed class MethodTable : MetadataTable<MethodRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 (rows [i].Col1); // RVA
- buffer.WriteUInt16 ((ushort) rows [i].Col2); // ImplFlags
- buffer.WriteUInt16 ((ushort) rows [i].Col3); // Flags
- buffer.WriteString (rows [i].Col4); // Name
- buffer.WriteBlob (rows [i].Col5); // Signature
- buffer.WriteRID (rows [i].Col6, Table.Param); // ParamList
- }
- }
- }
- sealed class ParamTable : MetadataTable<ParamRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
- buffer.WriteUInt16 (rows [i].Col2); // Sequence
- buffer.WriteString (rows [i].Col3); // Name
- }
- }
- }
- sealed class InterfaceImplTable : MetadataTable<InterfaceImplRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Interface
- }
- }
- /*public override int Compare (InterfaceImplRow x, InterfaceImplRow y)
- {
- return (int) (x.Col1 == y.Col1 ? y.Col2 - x.Col2 : x.Col1 - y.Col1);
- }*/
- }
- sealed class MemberRefTable : MetadataTable<MemberRefRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MemberRefParent);
- buffer.WriteString (rows [i].Col2);
- buffer.WriteBlob (rows [i].Col3);
- }
- }
- }
- sealed class ConstantTable : SortedTable<ConstantRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1);
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasConstant);
- buffer.WriteBlob (rows [i].Col3);
- }
- }
- public override int Compare (ConstantRow x, ConstantRow y)
- {
- return Compare (x.Col2, y.Col2);
- }
- }
- sealed class CustomAttributeTable : SortedTable<CustomAttributeRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomAttribute); // Parent
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.CustomAttributeType); // Type
- buffer.WriteBlob (rows [i].Col3);
- }
- }
- public override int Compare (CustomAttributeRow x, CustomAttributeRow y)
- {
- return Compare (x.Col1, y.Col1);
- }
- }
- sealed class FieldMarshalTable : SortedTable<FieldMarshalRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasFieldMarshal);
- buffer.WriteBlob (rows [i].Col2);
- }
- }
- public override int Compare (FieldMarshalRow x, FieldMarshalRow y)
- {
- return Compare (x.Col1, y.Col1);
- }
- }
- sealed class DeclSecurityTable : SortedTable<DeclSecurityRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1);
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasDeclSecurity);
- buffer.WriteBlob (rows [i].Col3);
- }
- }
- public override int Compare (DeclSecurityRow x, DeclSecurityRow y)
- {
- return Compare (x.Col2, y.Col2);
- }
- }
- sealed class ClassLayoutTable : SortedTable<ClassLayoutRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 (rows [i].Col1); // PackingSize
- buffer.WriteUInt32 (rows [i].Col2); // ClassSize
- buffer.WriteRID (rows [i].Col3, Table.TypeDef); // Parent
- }
- }
- public override int Compare (ClassLayoutRow x, ClassLayoutRow y)
- {
- return Compare (x.Col3, y.Col3);
- }
- }
- sealed class FieldLayoutTable : SortedTable<FieldLayoutRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 (rows [i].Col1); // Offset
- buffer.WriteRID (rows [i].Col2, Table.Field); // Parent
- }
- }
- public override int Compare (FieldLayoutRow x, FieldLayoutRow y)
- {
- return Compare (x.Col2, y.Col2);
- }
- }
- sealed class StandAloneSigTable : MetadataTable<uint> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++)
- buffer.WriteBlob (rows [i]);
- }
- }
- sealed class EventMapTable : MetadataTable<EventMapRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
- buffer.WriteRID (rows [i].Col2, Table.Event); // EventList
- }
- }
- }
- sealed class EventTable : MetadataTable<EventRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
- buffer.WriteString (rows [i].Col2); // Name
- buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeDefOrRef); // EventType
- }
- }
- }
- sealed class PropertyMapTable : MetadataTable<PropertyMapRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
- buffer.WriteRID (rows [i].Col2, Table.Property); // PropertyList
- }
- }
- }
- sealed class PropertyTable : MetadataTable<PropertyRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
- buffer.WriteString (rows [i].Col2); // Name
- buffer.WriteBlob (rows [i].Col3); // Type
- }
- }
- }
- sealed class MethodSemanticsTable : SortedTable<MethodSemanticsRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
- buffer.WriteRID (rows [i].Col2, Table.Method); // Method
- buffer.WriteCodedRID (rows [i].Col3, CodedIndex.HasSemantics); // Association
- }
- }
- public override int Compare (MethodSemanticsRow x, MethodSemanticsRow y)
- {
- return Compare (x.Col3, y.Col3);
- }
- }
- sealed class MethodImplTable : MetadataTable<MethodImplRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MethodDefOrRef); // MethodBody
- buffer.WriteCodedRID (rows [i].Col3, CodedIndex.MethodDefOrRef); // MethodDeclaration
- }
- }
- }
- sealed class ModuleRefTable : MetadataTable<uint> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++)
- buffer.WriteString (rows [i]); // Name
- }
- }
- sealed class TypeSpecTable : MetadataTable<uint> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++)
- buffer.WriteBlob (rows [i]); // Signature
- }
- }
- sealed class ImplMapTable : SortedTable<ImplMapRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MemberForwarded); // MemberForwarded
- buffer.WriteString (rows [i].Col3); // ImportName
- buffer.WriteRID (rows [i].Col4, Table.ModuleRef); // ImportScope
- }
- }
- public override int Compare (ImplMapRow x, ImplMapRow y)
- {
- return Compare (x.Col2, y.Col2);
- }
- }
- sealed class FieldRVATable : SortedTable<FieldRVARow> {
- internal int position;
- public override void Write (TableHeapBuffer buffer)
- {
- position = buffer.position;
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 (rows [i].Col1); // RVA
- buffer.WriteRID (rows [i].Col2, Table.Field); // Field
- }
- }
- public override int Compare (FieldRVARow x, FieldRVARow y)
- {
- return Compare (x.Col2, y.Col2);
- }
- }
- sealed class AssemblyTable : OneRowTable<AssemblyRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- buffer.WriteUInt32 ((uint) row.Col1); // AssemblyHashAlgorithm
- buffer.WriteUInt16 (row.Col2); // MajorVersion
- buffer.WriteUInt16 (row.Col3); // MinorVersion
- buffer.WriteUInt16 (row.Col4); // Build
- buffer.WriteUInt16 (row.Col5); // Revision
- buffer.WriteUInt32 ((uint) row.Col6); // Flags
- buffer.WriteBlob (row.Col7); // PublicKey
- buffer.WriteString (row.Col8); // Name
- buffer.WriteString (row.Col9); // Culture
- }
- }
- sealed class AssemblyRefTable : MetadataTable<AssemblyRefRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 (rows [i].Col1); // MajorVersion
- buffer.WriteUInt16 (rows [i].Col2); // MinorVersion
- buffer.WriteUInt16 (rows [i].Col3); // Build
- buffer.WriteUInt16 (rows [i].Col4); // Revision
- buffer.WriteUInt32 ((uint) rows [i].Col5); // Flags
- buffer.WriteBlob (rows [i].Col6); // PublicKeyOrToken
- buffer.WriteString (rows [i].Col7); // Name
- buffer.WriteString (rows [i].Col8); // Culture
- buffer.WriteBlob (rows [i].Col9); // Hash
- }
- }
- }
- sealed class FileTable : MetadataTable<FileRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 ((uint) rows [i].Col1);
- buffer.WriteString (rows [i].Col2);
- buffer.WriteBlob (rows [i].Col3);
- }
- }
- }
- sealed class ExportedTypeTable : MetadataTable<ExportedTypeRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 ((uint) rows [i].Col1);
- buffer.WriteUInt32 (rows [i].Col2);
- buffer.WriteString (rows [i].Col3);
- buffer.WriteString (rows [i].Col4);
- buffer.WriteCodedRID (rows [i].Col5, CodedIndex.Implementation);
- }
- }
- }
- sealed class ManifestResourceTable : MetadataTable<ManifestResourceRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 (rows [i].Col1);
- buffer.WriteUInt32 ((uint) rows [i].Col2);
- buffer.WriteString (rows [i].Col3);
- buffer.WriteCodedRID (rows [i].Col4, CodedIndex.Implementation);
- }
- }
- }
- sealed class NestedClassTable : SortedTable<NestedClassRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.TypeDef); // NestedClass
- buffer.WriteRID (rows [i].Col2, Table.TypeDef); // EnclosingClass
- }
- }
- public override int Compare (NestedClassRow x, NestedClassRow y)
- {
- return Compare (x.Col1, y.Col1);
- }
- }
- sealed class GenericParamTable : MetadataTable<GenericParamRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 (rows [i].Col1); // Number
- buffer.WriteUInt16 ((ushort) rows [i].Col2); // Flags
- buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeOrMethodDef); // Owner
- buffer.WriteString (rows [i].Col4); // Name
- }
- }
- }
- sealed class MethodSpecTable : MetadataTable<MethodSpecRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MethodDefOrRef); // Method
- buffer.WriteBlob (rows [i].Col2); // Instantiation
- }
- }
- }
- sealed class GenericParamConstraintTable : MetadataTable<GenericParamConstraintRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.GenericParam); // Owner
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Constraint
- }
- }
- }
- sealed class DocumentTable : MetadataTable<DocumentRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteBlob (rows [i].Col1); // Name
- buffer.WriteGuid (rows [i].Col2); // HashAlgorithm
- buffer.WriteBlob (rows [i].Col3); // Hash
- buffer.WriteGuid (rows [i].Col4); // Language
- }
- }
- }
- sealed class MethodDebugInformationTable : MetadataTable<MethodDebugInformationRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.Document); // Document
- buffer.WriteBlob (rows [i].Col2); // SequencePoints
- }
- }
- }
- sealed class LocalScopeTable : MetadataTable<LocalScopeRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.Method); // Method
- buffer.WriteRID (rows [i].Col2, Table.ImportScope); // ImportScope
- buffer.WriteRID (rows [i].Col3, Table.LocalVariable); // VariableList
- buffer.WriteRID (rows [i].Col4, Table.LocalConstant); // ConstantList
- buffer.WriteUInt32 (rows [i].Col5); // StartOffset
- buffer.WriteUInt32 (rows [i].Col6); // Length
- }
- }
- }
- sealed class LocalVariableTable : MetadataTable<LocalVariableRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
- buffer.WriteUInt16 (rows [i].Col2); // Index
- buffer.WriteString (rows [i].Col3); // Name
- }
- }
- }
- sealed class LocalConstantTable : MetadataTable<LocalConstantRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteString (rows [i].Col1); // Name
- buffer.WriteBlob (rows [i].Col2); // Signature
- }
- }
- }
- sealed class ImportScopeTable : MetadataTable<ImportScopeRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.ImportScope); // Parent
- buffer.WriteBlob (rows [i].Col2); // Imports
- }
- }
- }
- sealed class StateMachineMethodTable : MetadataTable<StateMachineMethodRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.Method); // MoveNextMethod
- buffer.WriteRID (rows [i].Col2, Table.Method); // KickoffMethod
- }
- }
- }
- sealed class CustomDebugInformationTable : SortedTable<CustomDebugInformationRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomDebugInformation); // Parent
- buffer.WriteGuid (rows [i].Col2); // Kind
- buffer.WriteBlob (rows [i].Col3); // Value
- }
- }
- public override int Compare (CustomDebugInformationRow x, CustomDebugInformationRow y)
- {
- return Compare(x.Col1, y.Col1);
- }
- }
- sealed class MetadataBuilder {
- readonly internal ModuleDefinition module;
- readonly internal ISymbolWriterProvider symbol_writer_provider;
- readonly internal ISymbolWriter symbol_writer;
- readonly internal TextMap text_map;
- readonly internal string fq_name;
- readonly internal uint timestamp;
- readonly Dictionary<TypeRefRow, MetadataToken> type_ref_map;
- readonly Dictionary<uint, MetadataToken> type_spec_map;
- readonly Dictionary<MemberRefRow, MetadataToken> member_ref_map;
- readonly Dictionary<MethodSpecRow, MetadataToken> method_spec_map;
- readonly Collection<GenericParameter> generic_parameters;
- readonly internal CodeWriter code;
- readonly internal DataBuffer data;
- readonly internal ResourceBuffer resources;
- readonly internal StringHeapBuffer string_heap;
- readonly internal GuidHeapBuffer guid_heap;
- readonly internal UserStringHeapBuffer user_string_heap;
- readonly internal BlobHeapBuffer blob_heap;
- readonly internal TableHeapBuffer table_heap;
- readonly internal PdbHeapBuffer pdb_heap;
- internal MetadataToken entry_point;
- internal RID type_rid = 1;
- internal RID field_rid = 1;
- internal RID method_rid = 1;
- internal RID param_rid = 1;
- internal RID property_rid = 1;
- internal RID event_rid = 1;
- internal RID local_variable_rid = 1;
- internal RID local_constant_rid = 1;
- readonly TypeRefTable type_ref_table;
- readonly TypeDefTable type_def_table;
- readonly FieldTable field_table;
- readonly MethodTable method_table;
- readonly ParamTable param_table;
- readonly InterfaceImplTable iface_impl_table;
- readonly MemberRefTable member_ref_table;
- readonly ConstantTable constant_table;
- readonly CustomAttributeTable custom_attribute_table;
- readonly DeclSecurityTable declsec_table;
- readonly StandAloneSigTable standalone_sig_table;
- readonly EventMapTable event_map_table;
- readonly EventTable event_table;
- readonly PropertyMapTable property_map_table;
- readonly PropertyTable property_table;
- readonly TypeSpecTable typespec_table;
- readonly MethodSpecTable method_spec_table;
- readonly bool portable_pdb;
- internal MetadataBuilder metadata_builder;
- readonly DocumentTable document_table;
- readonly MethodDebugInformationTable method_debug_information_table;
- readonly LocalScopeTable local_scope_table;
- readonly LocalVariableTable local_variable_table;
- readonly LocalConstantTable local_constant_table;
- readonly ImportScopeTable import_scope_table;
- readonly StateMachineMethodTable state_machine_method_table;
- readonly CustomDebugInformationTable custom_debug_information_table;
- readonly Dictionary<ImportScopeRow, MetadataToken> import_scope_map;
- readonly Dictionary<string, MetadataToken> document_map;
- public MetadataBuilder (ModuleDefinition module, string fq_name, uint timestamp, ISymbolWriterProvider symbol_writer_provider, ISymbolWriter symbol_writer)
- {
- this.module = module;
- this.text_map = CreateTextMap ();
- this.fq_name = fq_name;
- this.timestamp = timestamp;
- this.symbol_writer_provider = symbol_writer_provider;
- if (symbol_writer == null && module.HasImage && module.Image.HasDebugTables ()) {
- symbol_writer = new PortablePdbWriter (this, module);
- }
- this.symbol_writer = symbol_writer;
- var pdb_writer = symbol_writer as IMetadataSymbolWriter;
- if (pdb_writer != null) {
- portable_pdb = true;
- pdb_writer.SetMetadata (this);
- }
- this.code = new CodeWriter (this);
- this.data = new DataBuffer ();
- this.resources = new ResourceBuffer ();
- this.string_heap = new StringHeapBuffer ();
- this.guid_heap = new GuidHeapBuffer ();
- this.user_string_heap = new UserStringHeapBuffer ();
- this.blob_heap = new BlobHeapBuffer ();
- this.table_heap = new TableHeapBuffer (module, this);
- this.type_ref_table = GetTable<TypeRefTable> (Table.TypeRef);
- this.type_def_table = GetTable<TypeDefTable> (Table.TypeDef);
- this.field_table = GetTable<FieldTable> (Table.Field);
- this.method_table = GetTable<MethodTable> (Table.Method);
- this.param_table = GetTable<ParamTable> (Table.Param);
- this.iface_impl_table = GetTable<InterfaceImplTable> (Table.InterfaceImpl);
- this.member_ref_table = GetTable<MemberRefTable> (Table.MemberRef);
- this.constant_table = GetTable<ConstantTable> (Table.Constant);
- this.custom_attribute_table = GetTable<CustomAttributeTable> (Table.CustomAttribute);
- this.declsec_table = GetTable<DeclSecurityTable> (Table.DeclSecurity);
- this.standalone_sig_table = GetTable<StandAloneSigTable> (Table.StandAloneSig);
- this.event_map_table = GetTable<EventMapTable> (Table.EventMap);
- this.event_table = GetTable<EventTable> (Table.Event);
- this.property_map_table = GetTable<PropertyMapTable> (Table.PropertyMap);
- this.property_table = GetTable<PropertyTable> (Table.Property);
- this.typespec_table = GetTable<TypeSpecTable> (Table.TypeSpec);
- this.method_spec_table = GetTable<MethodSpecTable> (Table.MethodSpec);
- var row_equality_comparer = new RowEqualityComparer ();
- type_ref_map = new Dictionary<TypeRefRow, MetadataToken> (row_equality_comparer);
- type_spec_map = new Dictionary<uint, MetadataToken> ();
- member_ref_map = new Dictionary<MemberRefRow, MetadataToken> (row_equality_comparer);
- method_spec_map = new Dictionary<MethodSpecRow, MetadataToken> (row_equality_comparer);
- generic_parameters = new Collection<GenericParameter> ();
- if (!portable_pdb)
- return;
- this.document_table = GetTable<DocumentTable> (Table.Document);
- this.method_debug_information_table = GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation);
- this.local_scope_table = GetTable<LocalScopeTable> (Table.LocalScope);
- this.local_variable_table = GetTable<LocalVariableTable> (Table.LocalVariable);
- this.local_constant_table = GetTable<LocalConstantTable> (Table.LocalConstant);
- this.import_scope_table = GetTable<ImportScopeTable> (Table.ImportScope);
- this.state_machine_method_table = GetTable<StateMachineMethodTable> (Table.StateMachineMethod);
- this.custom_debug_information_table = GetTable<CustomDebugInformationTable> (Table.CustomDebugInformation);
- this.document_map = new Dictionary<string, MetadataToken> (StringComparer.Ordinal);
- this.import_scope_map = new Dictionary<ImportScopeRow, MetadataToken> (row_equality_comparer);
- }
- public MetadataBuilder (ModuleDefinition module, PortablePdbWriterProvider writer_provider)
- {
- this.module = module;
- this.text_map = new TextMap ();
- this.symbol_writer_provider = writer_provider;
- this.portable_pdb = true;
- this.string_heap = new StringHeapBuffer ();
- this.guid_heap = new GuidHeapBuffer ();
- this.user_string_heap = new UserStringHeapBuffer ();
- this.blob_heap = new BlobHeapBuffer ();
- this.table_heap = new TableHeapBuffer (module, this);
- this.pdb_heap = new PdbHeapBuffer();
- this.document_table = GetTable<DocumentTable> (Table.Document);
- this.method_debug_information_table = GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation);
- this.local_scope_table = GetTable<LocalScopeTable> (Table.LocalScope);
- this.local_variable_table = GetTable<LocalVariableTable> (Table.LocalVariable);
- this.local_constant_table = GetTable<LocalConstantTable> (Table.LocalConstant);
- this.import_scope_table = GetTable<ImportScopeTable> (Table.ImportScope);
- this.state_machine_method_table = GetTable<StateMachineMethodTable> (Table.StateMachineMethod);
- this.custom_debug_information_table = GetTable<CustomDebugInformationTable> (Table.CustomDebugInformation);
- var row_equality_comparer = new RowEqualityComparer ();
- this.document_map = new Dictionary<string, MetadataToken> ();
- this.import_scope_map = new Dictionary<ImportScopeRow, MetadataToken> (row_equality_comparer);
- }
- TextMap CreateTextMap ()
- {
- var map = new TextMap ();
- map.AddMap (TextSegment.ImportAddressTable, module.Architecture == TargetArchitecture.I386 ? 8 : 0);
- map.AddMap (TextSegment.CLIHeader, 0x48, 8);
- return map;
- }
- TTable GetTable<TTable> (Table table) where TTable : MetadataTable, new ()
- {
- return table_heap.GetTable<TTable> (table);
- }
- uint GetStringIndex (string @string)
- {
- if (string.IsNullOrEmpty (@string))
- return 0;
- return string_heap.GetStringIndex (@string);
- }
- uint GetGuidIndex (Guid guid)
- {
- return guid_heap.GetGuidIndex (guid);
- }
- uint GetBlobIndex (ByteBuffer blob)
- {
- if (blob.length == 0)
- return 0;
- return blob_heap.GetBlobIndex (blob);
- }
- uint GetBlobIndex (byte [] blob)
- {
- if (blob.IsNullOrEmpty ())
- return 0;
- return GetBlobIndex (new ByteBuffer (blob));
- }
- public void BuildMetadata ()
- {
- BuildModule ();
- table_heap.string_offsets = string_heap.WriteStrings ();
- table_heap.ComputeTableInformations ();
- table_heap.WriteTableHeap ();
- }
- void BuildModule ()
- {
- var table = GetTable<ModuleTable> (Table.Module);
- table.row.Col1 = GetStringIndex (module.Name);
- table.row.Col2 = GetGuidIndex (module.Mvid);
- var assembly = module.Assembly;
- if (assembly != null)
- BuildAssembly ();
- if (module.HasAssemblyReferences)
- AddAssemblyReferences ();
- if (module.HasModuleReferences)
- AddModuleReferences ();
- if (module.HasResources)
- AddResources ();
- if (module.HasExportedTypes)
- AddExportedTypes ();
- BuildTypes ();
- if (assembly != null) {
- if (assembly.HasCustomAttributes)
- AddCustomAttributes (assembly);
- if (assembly.HasSecurityDeclarations)
- AddSecurityDeclarations (assembly);
- }
- if (module.HasCustomAttributes)
- AddCustomAttributes (module);
- if (module.EntryPoint != null)
- entry_point = LookupToken (module.EntryPoint);
- var pdb_writer = symbol_writer as IMetadataSymbolWriter;
- if (pdb_writer != null)
- pdb_writer.WriteModule ();
- }
- void BuildAssembly ()
- {
- var assembly = module.Assembly;
- var name = assembly.Name;
- var table = GetTable<AssemblyTable> (Table.Assembly);
- table.row = new AssemblyRow (
- name.HashAlgorithm,
- (ushort) name.Version.Major,
- (ushort) name.Version.Minor,
- (ushort) name.Version.Build,
- (ushort) name.Version.Revision,
- name.Attributes,
- GetBlobIndex (name.PublicKey),
- GetStringIndex (name.Name),
- GetStringIndex (name.Culture));
- if (assembly.Modules.Count > 1)
- BuildModules ();
- }
- void BuildModules ()
- {
- var modules = this.module.Assembly.Modules;
- var table = GetTable<FileTable> (Table.File);
- for (int i = 0; i < modules.Count; i++) {
- var module = modules [i];
- if (module.IsMain)
- continue;
- #if NET_CORE
- throw new NotSupportedException ();
- #else
- var parameters = new WriterParameters {
- SymbolWriterProvider = symbol_writer_provider,
- };
- var file_name = GetModuleFileName (module.Name);
- module.Write (file_name, parameters);
- var hash = CryptoService.ComputeHash (file_name);
- table.AddRow (new FileRow (
- FileAttributes.ContainsMetaData,
- GetStringIndex (module.Name),
- GetBlobIndex (hash)));
- #endif
- }
- }
- #if !NET_CORE
- string GetModuleFileName (string name)
- {
- if (string.IsNullOrEmpty (name))
- throw new NotSupportedException ();
- var path = Path.GetDirectoryName (fq_name);
- return Path.Combine (path, name);
- }
- #endif
- void AddAssemblyReferences ()
- {
- var references = module.AssemblyReferences;
- var table = GetTable<AssemblyRefTable> (Table.AssemblyRef);
- if (module.IsWindowsMetadata ())
- module.Projections.RemoveVirtualReferences (references);
- for (int i = 0; i < references.Count; i++) {
- var reference = references [i];
- var key_or_token = reference.PublicKey.IsNullOrEmpty ()
- ? reference.PublicKeyToken
- : reference.PublicKey;
- var version = reference.Version;
- var rid = table.AddRow (new AssemblyRefRow (
- (ushort) version.Major,
- (ushort) version.Minor,
- (ushort) version.Build,
- (ushort) version.Revision,
- reference.Attributes,
- GetBlobIndex (key_or_token),
- GetStringIndex (reference.Name),
- GetStringIndex (reference.Culture),
- GetBlobIndex (reference.Hash)));
- reference.token = new MetadataToken (TokenType.AssemblyRef, rid);
- }
- if (module.IsWindowsMetadata ())
- module.Projections.AddVirtualReferences (references);
- }
- void AddModuleReferences ()
- {
- var references = module.ModuleReferences;
- var table = GetTable<ModuleRefTable> (Table.ModuleRef);
- for (int i = 0; i < references.Count; i++) {
- var reference = references [i];
- reference.token = new MetadataToken (
- TokenType.ModuleRef,
- table.AddRow (GetStringIndex (reference.Name)));
- }
- }
- void AddResources ()
- {
- var resources = module.Resources;
- var table = GetTable<ManifestResourceTable> (Table.ManifestResource);
- for (int i = 0; i < resources.Count; i++) {
- var resource = resources [i];
- var row = new ManifestResourceRow (
- 0,
- resource.Attributes,
- GetStringIndex (resource.Name),
- 0);
- switch (resource.ResourceType) {
- case ResourceType.Embedded:
- row.Col1 = AddEmbeddedResource ((EmbeddedResource) resource);
- break;
- case ResourceType.Linked:
- row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
- new MetadataToken (
- TokenType.File,
- AddLinkedResource ((LinkedResource) resource)));
- break;
- case ResourceType.AssemblyLinked:
- row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
- ((AssemblyLinkedResource) resource).Assembly.MetadataToken);
- break;
- default:
- throw new NotSupportedException ();
- }
- table.AddRow (row);
- }
- }
- uint AddLinkedResource (LinkedResource resource)
- {
- var table = GetTable<FileTable> (Table.File);
- var hash = resource.Hash;
- #if !NET_CORE
- if (hash.IsNullOrEmpty ())
- hash = CryptoService.ComputeHash (resource.File);
- #endif
- return (uint) table.AddRow (new FileRow (
- FileAttributes.ContainsNoMetaData,
- GetStringIndex (resource.File),
- GetBlobIndex (hash)));
- }
- uint AddEmbeddedResource (EmbeddedResource resource)
- {
- return resources.AddResource (resource.GetResourceData ());
- }
- void AddExportedTypes ()
- {
- var exported_types = module.ExportedTypes;
- var table = GetTable<ExportedTypeTable> (Table.ExportedType);
- for (int i = 0; i < exported_types.Count; i++) {
- var exported_type = exported_types [i];
- var rid = table.AddRow (new ExportedTypeRow (
- exported_type.Attributes,
- (uint) exported_type.Identifier,
- GetStringIndex (exported_type.Name),
- GetStringIndex (exported_type.Namespace),
- MakeCodedRID (GetExportedTypeScope (exported_type), CodedIndex.Implementation)));
- exported_type.token = new MetadataToken (TokenType.ExportedType, rid);
- }
- }
- MetadataToken GetExportedTypeScope (ExportedType exported_type)
- {
- if (exported_type.DeclaringType != null)
- return exported_type.DeclaringType.MetadataToken;
- var scope = exported_type.Scope;
- switch (scope.MetadataToken.TokenType) {
- case TokenType.AssemblyRef:
- return scope.MetadataToken;
- case TokenType.ModuleRef:
- var file_table = GetTable<FileTable> (Table.File);
- for (int i = 0; i < file_table.length; i++)
- if (file_table.rows [i].Col2 == GetStringIndex (scope.Name))
- return new MetadataToken (TokenType.File, i + 1);
- break;
- }
- throw new NotSupportedException ();
- }
- void BuildTypes ()
- {
- if (!module.HasTypes)
- return;
- AttachTokens ();
- AddTypes ();
- AddGenericParameters ();
- }
- void AttachTokens ()
- {
- var types = module.Types;
- for (int i = 0; i < types.Count; i++)
- AttachTypeToken (types [i]);
- }
- void AttachTypeToken (TypeDefinition type)
- {
- type.token = new MetadataToken (TokenType.TypeDef, type_rid++);
- type.fields_range.Start = field_rid;
- type.methods_range.Start = method_rid;
- if (type.HasFields)
- AttachFieldsToken (type);
- if (type.HasMethods)
- AttachMethodsToken (type);
- if (type.HasNestedTypes)
- AttachNestedTypesToken (type);
- }
- void AttachNestedTypesToken (TypeDefinition type)
- {
- var nested_types = type.NestedTypes;
- for (int i = 0; i < nested_types.Count; i++)
- AttachTypeToken (nested_types [i]);
- }
- void AttachFieldsToken (TypeDefinition type)
- {
- var fields = type.Fields;
- type.fields_range.Length = (uint) fields.Count;
- for (int i = 0; i < fields.Count; i++)
- fields [i].token = new MetadataToken (TokenType.Field, field_rid++);
- }
- void AttachMethodsToken (TypeDefinition type)
- {
- var methods = type.Methods;
- type.methods_range.Length = (uint) methods.Count;
- for (int i = 0; i < methods.Count; i++)
- methods [i].token = new MetadataToken (TokenType.Method, method_rid++);
- }
- MetadataToken GetTypeToken (TypeReference type)
- {
- if (type == null)
- return MetadataToken.Zero;
- if (type.IsDefinition)
- return type.token;
- if (type.IsTypeSpecification ())
- return GetTypeSpecToken (type);
- return GetTypeRefToken (type);
- }
- MetadataToken GetTypeSpecToken (TypeReference type)
- {
- var row = GetBlobIndex (GetTypeSpecSignature (type));
- MetadataToken token;
- if (type_spec_map.TryGetValue (row, out token))
- return token;
- return AddTypeSpecification (type, row);
- }
- MetadataToken AddTypeSpecification (TypeReference type, uint row)
- {
- type.token = new MetadataToken (TokenType.TypeSpec, typespec_table.AddRow (row));
- var token = type.token;
- type_spec_map.Add (row, token);
- return token;
- }
- MetadataToken GetTypeRefToken (TypeReference type)
- {
- var projection = WindowsRuntimeProjections.RemoveProjection (type);
- var row = CreateTypeRefRow (type);
- MetadataToken token;
- if (!type_ref_map.TryGetValue (row, out token))
- token = AddTypeReference (type, row);
- WindowsRuntimeProjections.ApplyProjection (type, projection);
- return token;
- }
- TypeRefRow CreateTypeRefRow (TypeReference type)
- {
- var scope_token = GetScopeToken (type);
- return new TypeRefRow (
- MakeCodedRID (scope_token, CodedIndex.ResolutionScope),
- GetStringIndex (type.Name),
- GetStringIndex (type.Namespace));
- }
- MetadataToken GetScopeToken (TypeReference type)
- {
- if (type.IsNested)
- return GetTypeRefToken (type.DeclaringType);
- var scope = type.Scope;
- if (scope == null)
- return MetadataToken.Zero;
- return scope.MetadataToken;
- }
- static CodedRID MakeCodedRID (IMetadataTokenProvider provider, CodedIndex index)
- {
- return MakeCodedRID (provider.MetadataToken, index);
- }
- static CodedRID MakeCodedRID (MetadataToken token, CodedIndex index)
- {
- return index.CompressMetadataToken (token);
- }
- MetadataToken AddTypeReference (TypeReference type, TypeRefRow row)
- {
- type.token = new MetadataToken (TokenType.TypeRef, type_ref_table.AddRow (row));
- var token = type.token;
- type_ref_map.Add (row, token);
- return token;
- }
- void AddTypes ()
- {
- var types = module.Types;
- for (int i = 0; i < types.Count; i++)
- AddType (types [i]);
- }
- void AddType (TypeDefinition type)
- {
- var treatment = WindowsRuntimeProjections.RemoveProjection (type);
- type_def_table.AddRow (new TypeDefRow (
- type.Attributes,
- GetStringIndex (type.Name),
- GetStringIndex (type.Namespace),
- MakeCodedRID (GetTypeToken (type.BaseType), CodedIndex.TypeDefOrRef),
- type.fields_range.Start,
- type.methods_range.Start));
- if (type.HasGenericParameters)
- AddGenericParameters (type);
- if (type.HasInterfaces)
- AddInterfaces (type);
- AddLayoutInfo (type);
- if (type.HasFields)
- AddFields (type);
- if (type.HasMethods)
- AddMethods (type);
- if (type.HasProperties)
- AddProperties (type);
- if (type.HasEvents)
- AddEvents (type);
- if (type.HasCustomAttributes)
- AddCustomAttributes (type);
- if (type.HasSecurityDeclarations)
- AddSecurityDeclarations (type);
- if (type.HasNestedTypes)
- AddNestedTypes (type);
- WindowsRuntimeProjections.ApplyProjection (type, treatment);
- }
- void AddGenericParameters (IGenericParameterProvider owner)
- {
- var parameters = owner.GenericParameters;
- for (int i = 0; i < parameters.Count; i++)
- generic_parameters.Add (parameters [i]);
- }
- sealed class GenericParameterComparer : IComparer<GenericParameter> {
- public int Compare (GenericParameter a, GenericParameter b)
- {
- var a_owner = MakeCodedRID (a.Owner, CodedIndex.TypeOrMethodDef);
- var b_owner = MakeCodedRID (b.Owner, CodedIndex.TypeOrMethodDef);
- if (a_owner == b_owner) {
- var a_pos = a.Position;
- var b_pos = b.Position;
- return a_pos == b_pos ? 0 : a_pos > b_pos ? 1 : -1;
- }
- return a_owner > b_owner ? 1 : -1;
- }
- }
- void AddGenericParameters ()
- {
- var items = this.generic_parameters.items;
- var size = this.generic_parameters.size;
- Array.Sort (items, 0, size, new GenericParameterComparer ());
- var generic_param_table = GetTable<GenericParamTable> (Table.GenericParam);
- var generic_param_constraint_table = GetTable<GenericParamConstraintTable> (Table.GenericParamConstraint);
- for (int i = 0; i < size; i++) {
- var generic_parameter = items [i];
- var rid = generic_param_table.AddRow (new GenericParamRow (
- (ushort) generic_parameter.Position,
- generic_parameter.Attributes,
- MakeCodedRID (generic_parameter.Owner, CodedIndex.TypeOrMethodDef),
- GetStringIndex (generic_parameter.Name)));
- generic_parameter.token = new MetadataToken (TokenType.GenericParam, rid);
- if (generic_parameter.HasConstraints)
- AddConstraints (generic_parameter, generic_param_constraint_table);
- if (generic_parameter.HasCustomAttributes)
- AddCustomAttributes (generic_parameter);
- }
- }
- void AddConstraints (GenericParameter generic_parameter, GenericParamConstraintTable table)
- {
- var constraints = generic_parameter.Constraints;
- var rid = generic_parameter.token.RID;
- for (int i = 0; i < constraints.Count; i++)
- table.AddRow (new GenericParamConstraintRow (
- rid,
- MakeCodedRID (GetTypeToken (constraints [i]), CodedIndex.TypeDefOrRef)));
- }
- void AddInterfaces (TypeDefinition type)
- {
- var interfaces = type.Interfaces;
- var type_rid = type.token.RID;
- for (int i = 0; i < interfaces.Count; i++) {
- var iface_impl = interfaces [i];
- var rid = iface_impl_table.AddRow (new InterfaceImplRow (
- type_rid,
- MakeCodedRID (GetTypeToken (iface_impl.InterfaceType), CodedIndex.TypeDefOrRef)));
- iface_impl.token = new MetadataToken (TokenType.InterfaceImpl, rid);
- if (iface_impl.HasCustomAttributes)
- AddCustomAttributes (iface_impl);
- }
- }
- void AddLayoutInfo (TypeDefinition type)
- {
- if (type.HasLayoutInfo) {
- var table = GetTable<ClassLayoutTable> (Table.ClassLayout);
- table.AddRow (new ClassLayoutRow (
- (ushort) type.PackingSize,
- (uint) type.ClassSize,
- type.token.RID));
- return;
- }
- if (type.IsValueType && HasNoInstanceField (type)) {
- var table = GetTable<ClassLayoutTable> (Table.ClassLayout);
- table.AddRow (new ClassLayoutRow (0, 1, type.token.RID));
- }
- }
- static bool HasNoInstanceField (TypeDefinition type)
- {
- if (!type.HasFields)
- return true;
- var fields = type.Fields;
- for (int i = 0; i < fields.Count; i++)
- if (!fields [i].IsStatic)
- return false;
- return true;
- }
- void AddNestedTypes (TypeDefinition type)
- {
- var nested_types = type.NestedTypes;
- var nested_table = GetTable<NestedClassTable> (Table.NestedClass);
- for (int i = 0; i < nested_types.Count; i++) {
- var nested = nested_types [i];
- AddType (nested);
- nested_table.AddRow (new NestedClassRow (nested.token.RID, type.token.RID));
- }
- }
- void AddFields (TypeDefinition type)
- {
- var fields = type.Fields;
- for (int i = 0; i < fields.Count; i++)
- AddField (fields [i]);
- }
- void AddField (FieldDefinition field)
- {
- var projection = WindowsRuntimeProjections.RemoveProjection (field);
- field_table.AddRow (new FieldRow (
- field.Attributes,
- GetStringIndex (field.Name),
- GetBlobIndex (GetFieldSignature (field))));
- if (!field.InitialValue.IsNullOrEmpty ())
- AddFieldRVA (field);
- if (field.HasLayoutInfo)
- AddFieldLayout (field);
- if (field.HasCustomAttributes)
- AddCustomAttributes (field);
- if (field.HasConstant)
- AddConstant (field, field.FieldType);
- if (field.HasMarshalInfo)
- AddMarshalInfo (field);
- WindowsRuntimeProjections.ApplyProjection (field, projection);
- }
- void AddFieldRVA (FieldDefinition field)
- {
- var table = GetTable<FieldRVATable> (Table.FieldRVA);
- table.AddRow (new FieldRVARow (
- data.AddData (field.InitialValue),
- field.token.RID));
- }
- void AddFieldLayout (FieldDefinition field)
- {
- var table = GetTable<FieldLayoutTable> (Table.FieldLayout);
- table.AddRow (new FieldLayoutRow ((uint) field.Offset, field.token.RID));
- }
- void AddMethods (TypeDefinition type)
- {
- var methods = type.Methods;
- for (int i = 0; i < methods.Count; i++)
- AddMethod (methods [i]);
- }
- void AddMethod (MethodDefinition method)
- {
- var projection = WindowsRuntimeProjections.RemoveProjection (method);
- method_table.AddRow (new MethodRow (
- method.HasBody ? code.WriteMethodBody (method) : 0,
- method.ImplAttributes,
- method.Attributes,
- GetStringIndex (method.Name),
- GetBlobIndex (GetMethodSignature (method)),
- param_rid));
- AddParameters (method);
- if (method.HasGenericParameters)
- AddGenericParameters (method);
- if (method.IsPInvokeImpl)
- AddPInvokeInfo (method);
- if (method.HasCustomAttributes)
- AddCustomAttributes (method);
- if (method.HasSecurityDeclarations)
- AddSecurityDeclarations (method);
- if (method.HasOverrides)
- AddOverrides (method);
- WindowsRuntimeProjections.ApplyProjection (method, projection);
- }
- void AddParameters (MethodDefinition method)
- {
- var return_parameter = method.MethodReturnType.parameter;
- if (return_parameter != null && RequiresParameterRow (return_parameter))
- AddParameter (0, return_parameter, param_table);
- if (!method.HasParameters)
- return;
- var parameters = method.Parameters;
- for (int i = 0; i < parameters.Count; i++) {
- var parameter = parameters [i];
- if (!RequiresParameterRow (parameter))
- continue;
- AddParameter ((ushort) (i + 1), parameter, param_table);
- }
- }
- void AddPInvokeInfo (MethodDefinition method)
- {
- var pinvoke = method.PInvokeInfo;
- if (pinvoke == null)
- return;
- var table = GetTable<ImplMapTable> (Table.ImplMap);
- table.AddRow (new ImplMapRow (
- pinvoke.Attributes,
- MakeCodedRID (method, CodedIndex.MemberForwarded),
- GetStringIndex (pinvoke.EntryPoint),
- pinvoke.Module.MetadataToken.RID));
- }
- void AddOverrides (MethodDefinition method)
- {
- var overrides = method.Overrides;
- var table = GetTable<MethodImplTable> (Table.MethodImpl);
- for (int i = 0; i < overrides.Count; i++) {
- table.AddRow (new MethodImplRow (
- method.DeclaringType.token.RID,
- MakeCodedRID (method, CodedIndex.MethodDefOrRef),
- MakeCodedRID (LookupToken (overrides [i]), CodedIndex.MethodDefOrRef)));
- }
- }
- static bool RequiresParameterRow (ParameterDefinition parameter)
- {
- return !string.IsNullOrEmpty (parameter.Name)
- || parameter.Attributes != ParameterAttributes.None
- || parameter.HasMarshalInfo
- || parameter.HasConstant
- || parameter.HasCustomAttributes;
- }
- void AddParameter (ushort sequence, ParameterDefinition parameter, ParamTable table)
- {
- table.AddRow (new ParamRow (
- parameter.Attributes,
- sequence,
- GetStringIndex (parameter.Name)));
- parameter.token = new MetadataToken (TokenType.Param, param_rid++);
- if (parameter.HasCustomAttributes)
- AddCustomAttributes (parameter);
- if (parameter.HasConstant)
- AddConstant (parameter, parameter.ParameterType);
- if (parameter.HasMarshalInfo)
- AddMarshalInfo (parameter);
- }
- void AddMarshalInfo (IMarshalInfoProvider owner)
- {
- var table = GetTable<FieldMarshalTable> (Table.FieldMarshal);
- table.AddRow (new FieldMarshalRow (
- MakeCodedRID (owner, CodedIndex.HasFieldMarshal),
- GetBlobIndex (GetMarshalInfoSignature (owner))));
- }
- void AddProperties (TypeDefinition type)
- {
- var properties = type.Properties;
- property_map_table.AddRow (new PropertyMapRow (type.token.RID, property_rid));
- for (int i = 0; i < properties.Count; i++)
- AddProperty (properties [i]);
- }
- void AddProperty (PropertyDefinition property)
- {
- property_table.AddRow (new PropertyRow (
- property.Attributes,
- GetStringIndex (property.Name),
- GetBlobIndex (GetPropertySignature (property))));
- property.token = new MetadataToken (TokenType.Property, property_rid++);
- var method = property.GetMethod;
- if (method != null)
- AddSemantic (MethodSemanticsAttributes.Getter, property, method);
- method = property.SetMethod;
- if (method != null)
- AddSemantic (MethodSemanticsAttributes.Setter, property, method);
- if (property.HasOtherMethods)
- AddOtherSemantic (property, property.OtherMethods);
- if (property.HasCustomAttributes)
- AddCustomAttributes (property);
- if (property.HasConstant)
- AddConstant (property, property.PropertyType);
- }
- void AddOtherSemantic (IMetadataTokenProvider owner, Collection<MethodDefinition> others)
- {
- for (int i = 0; i < others.Count; i++)
- AddSemantic (MethodSemanticsAttributes.Other, owner, others [i]);
- }
- void AddEvents (TypeDefinition type)
- {
- var events = type.Events;
- event_map_table.AddRow (new EventMapRow (type.token.RID, event_rid));
- for (int i = 0; i < events.Count; i++)
- AddEvent (events [i]);
- }
- void AddEvent (EventDefinition @event)
- {
- event_table.AddRow (new EventRow (
- @event.Attributes,
- GetStringIndex (@event.Name),
- MakeCodedRID (GetTypeToken (@event.EventType), CodedIndex.TypeDefOrRef)));
- @event.token = new MetadataToken (TokenType.Event, event_rid++);
- var method = @event.AddMethod;
- if (method != null)
- AddSemantic (MethodSemanticsAttributes.AddOn, @event, method);
- method = @event.InvokeMethod;
- if (method != null)
- AddSemantic (MethodSemanticsAttributes.Fire, @event, method);
- method = @event.RemoveMethod;
- if (method != null)
- AddSemantic (MethodSemanticsAttributes.RemoveOn, @event, method);
- if (@event.HasOtherMethods)
- AddOtherSemantic (@event, @event.OtherMethods);
- if (@event.HasCustomAttributes)
- AddCustomAttributes (@event);
- }
- void AddSemantic (MethodSemanticsAttributes semantics, IMetadataTokenProvider provider, MethodDefinition method)
- {
- method.SemanticsAttributes = semantics;
- var table = GetTable<MethodSemanticsTable> (Table.MethodSemantics);
- table.AddRow (new MethodSemanticsRow (
- semantics,
- method.token.RID,
- MakeCodedRID (provider, CodedIndex.HasSemantics)));
- }
- void AddConstant (IConstantProvider owner, TypeReference type)
- {
- var constant = owner.Constant;
- var etype = GetConstantType (type, constant);
- constant_table.AddRow (new ConstantRow (
- etype,
- MakeCodedRID (owner.MetadataToken, CodedIndex.HasConstant),
- GetBlobIndex (GetConstantSignature (etype, constant))));
- }
- static ElementType GetConstantType (TypeReference constant_type, object constant)
- {
- if (constant == null)
- return ElementType.Class;
- var etype = constant_type.etype;
- switch (etype) {
- case ElementType.None:
- var type = constant_type.CheckedResolve ();
- if (type.IsEnum)
- return GetConstantType (type.GetEnumUnderlyingType (), constant);
- return ElementType.Class;
- case ElementType.String:
- return ElementType.String;
- case ElementType.Object:
- return GetConstantType (constant.GetType ());
- case ElementType.Array:
- case ElementType.SzArray:
- case ElementType.MVar:
- case ElementType.Var:
- return ElementType.Class;
- case ElementType.GenericInst:
- var generic_instance = (GenericInstanceType) constant_type;
- if (generic_instance.ElementType.IsTypeOf ("System", "Nullable`1"))
- return GetConstantType (generic_instance.GenericArguments [0], constant);
- return GetConstantType (((TypeSpecification) constant_type).ElementType, constant);
- case ElementType.CModOpt:
- case ElementType.CModReqD:
- case ElementType.ByRef:
- case ElementType.Sentinel:
- return GetConstantType (((TypeSpecification) constant_type).ElementType, constant);
- case ElementType.Boolean:
- case ElementType.Char:
- case ElementType.I:
- case ElementType.I1:
- case ElementType.I2:
- case ElementType.I4:
- case ElementType.I8:
- case ElementType.U:
- case ElementType.U1:
- case ElementType.U2:
- case ElementType.U4:
- case ElementType.U8:
- case ElementType.R4:
- case ElementType.R8:
- return GetConstantType (constant.GetType ());
- default:
- return etype;
- }
- }
- static ElementType GetConstantType (Type type)
- {
- switch (type.GetTypeCode ()) {
- case TypeCode.Boolean:
- return ElementType.Boolean;
- case TypeCode.Byte:
- return ElementType.U1;
- case TypeCode.SByte:
- return ElementType.I1;
- case TypeCode.Char:
- return ElementType.Char;
- case TypeCode.Int16:
- return ElementType.I2;
- case TypeCode.UInt16:
- return ElementType.U2;
- case TypeCode.Int32:
- return ElementType.I4;
- case TypeCode.UInt32:
- return ElementType.U4;
- case TypeCode.Int64:
- return ElementType.I8;
- case TypeCode.UInt64:
- return ElementType.U8;
- case TypeCode.Single:
- return ElementType.R4;
- case TypeCode.Double:
- return ElementType.R8;
- case TypeCode.String:
- return ElementType.String;
- default:
- throw new NotSupportedException (type.FullName);
- }
- }
- void AddCustomAttributes (ICustomAttributeProvider owner)
- {
- var custom_attributes = owner.CustomAttributes;
- for (int i = 0; i < custom_attributes.Count; i++) {
- var attribute = custom_attributes [i];
- var projection = WindowsRuntimeProjections.RemoveProjection (attribute);
- custom_attribute_table.AddRow (new CustomAttributeRow (
- MakeCodedRID (owner, CodedIndex.HasCustomAttribute),
- MakeCodedRID (LookupToken (attribute.Constructor), CodedIndex.CustomAttributeType),
- GetBlobIndex (GetCustomAttributeSignature (attribute))));
- WindowsRuntimeProjections.ApplyProjection (attribute, projection);
- }
- }
- void AddSecurityDeclarations (ISecurityDeclarationProvider owner)
- {
- var declarations = owner.SecurityDeclarations;
- for (int i = 0; i < declarations.Count; i++) {
- var declaration = declarations [i];
- declsec_table.AddRow (new DeclSecurityRow (
- declaration.Action,
- MakeCodedRID (owner, CodedIndex.HasDeclSecurity),
- GetBlobIndex (GetSecurityDeclarationSignature (declaration))));
- }
- }
- MetadataToken GetMemberRefToken (MemberReference member)
- {
- var projection = WindowsRuntimeProjections.RemoveProjection (member);
- var row = CreateMemberRefRow (member);
- MetadataToken token;
- if (!member_ref_map.TryGetValue (row, out token))
- token = AddMemberReference (member, row);
- WindowsRuntimeProjections.ApplyProjection (member, projection);
- return token;
- }
- MemberRefRow CreateMemberRefRow (MemberReference member)
- {
- return new MemberRefRow (
- MakeCodedRID (GetTypeToken (member.DeclaringType), CodedIndex.MemberRefParent),
- GetStringIndex (member.Name),
- GetBlobIndex (GetMemberRefSignature (member)));
- }
- MetadataToken AddMemberReference (MemberReference member, MemberRefRow row)
- {
- member.token = new MetadataToken (TokenType.MemberRef, member_ref_table.AddRow (row));
- var token = member.token;
- member_ref_map.Add (row, token);
- return token;
- }
- MetadataToken GetMethodSpecToken (MethodSpecification method_spec)
- {
- var row = CreateMethodSpecRow (method_spec);
- MetadataToken token;
- if (method_spec_map.TryGetValue (row, out token))
- return token;
- AddMethodSpecification (method_spec, row);
- return method_spec.token;
- }
- void AddMethodSpecification (MethodSpecification method_spec, MethodSpecRow row)
- {
- method_spec.token = new MetadataToken (TokenType.MethodSpec, method_spec_table.AddRow (row));
- method_spec_map.Add (row, method_spec.token);
- }
- MethodSpecRow CreateMethodSpecRow (MethodSpecification method_spec)
- {
- return new MethodSpecRow (
- MakeCodedRID (LookupToken (method_spec.ElementMethod), CodedIndex.MethodDefOrRef),
- GetBlobIndex (GetMethodSpecSignature (method_spec)));
- }
- SignatureWriter CreateSignatureWriter ()
- {
- return new SignatureWriter (this);
- }
- SignatureWriter GetMethodSpecSignature (MethodSpecification method_spec)
- {
- if (!method_spec.IsGenericInstance)
- throw new NotSupportedException ();
- var generic_instance = (GenericInstanceMethod) method_spec;
- var signature = CreateSignatureWriter ();
- signature.WriteByte (0x0a);
- signature.WriteGenericInstanceSignature (generic_instance);
- return signature;
- }
- public uint AddStandAloneSignature (uint signature)
- {
- return (uint) standalone_sig_table.AddRow (signature);
- }
- public uint GetLocalVariableBlobIndex (Collection<VariableDefinition> variables)
- {
- return GetBlobIndex (GetVariablesSignature (variables));
- }
- public uint GetCallSiteBlobIndex (CallSite call_site)
- {
- return GetBlobIndex (GetMethodSignature (call_site));
- }
- public uint GetConstantTypeBlobIndex (TypeReference constant_type)
- {
- return GetBlobIndex (GetConstantTypeSignature (constant_type));
- }
- SignatureWriter GetVariablesSignature (Collection<VariableDefinition> variables)
- {
- var signature = CreateSignatureWriter ();
- signature.WriteByte (0x7);
- signature.WriteCompressedUInt32 ((uint) variables.Count);
- for (int i = 0; i < variables.Count; i++)
- signature.WriteTypeSignature (variables [i].VariableType);
- return signature;
- }
- SignatureWriter GetConstantTypeSignature (TypeReference constant_type)
- {
- var signature = CreateSignatureWriter ();
- signature.WriteByte (0x6);
- signature.WriteTypeSignature (constant_type);
- return signature;
- }
- SignatureWriter GetFieldSignature (FieldReference field)
- {
- var signature = CreateSignatureWriter ();
- signature.WriteByte (0x6);
- signature.WriteTypeSignature (field.FieldType);
- return signature;
- }
- SignatureWriter GetMethodSignature (IMethodSignature method)
- {
- var signature = CreateSignatureWriter ();
- signature.WriteMethodSignature (method);
- return signature;
- }
- SignatureWriter GetMemberRefSignature (MemberReference member)
- {
- var field = member as FieldReference;
- if (field != null)
- return GetFieldSignature (field);
- var method = member as MethodReference;
- if (method != null)
- return GetMethodSignature (method);
- throw new NotSupportedException ();
- }
- SignatureWriter GetPropertySignature (PropertyDefinition property)
- {
- var signature = CreateSignatureWriter ();
- byte calling_convention = 0x8;
- if (property.HasThis)
- calling_convention |= 0x20;
- uint param_count = 0;
- Collection<ParameterDefinition> parameters = null;
- if (property.HasParameters) {
- parameters = property.Parameters;
- param_count = (uint) parameters.Count;
- }
- signature.WriteByte (calling_convention);
- signature.WriteCompressedUInt32 (param_count);
- signature.WriteTypeSignature (property.PropertyType);
- if (param_count == 0)
- return signature;
- for (int i = 0; i < param_count; i++)
- signature.WriteTypeSignature (parameters [i].ParameterType);
- return signature;
- }
- SignatureWriter GetTypeSpecSignature (TypeReference type)
- {
- var signature = CreateSignatureWriter ();
- signature.WriteTypeSignature (type);
- return signature;
- }
- SignatureWriter GetConstantSignature (ElementType type, object value)
- {
- var signature = CreateSignatureWriter ();
- switch (type) {
- case ElementType.Array:
- case ElementType.SzArray:
- case ElementType.Class:
- case ElementType.Object:
- case ElementType.None:
- case ElementType.Var:
- case ElementType.MVar:
- signature.WriteInt32 (0);
- break;
- case ElementType.String:
- signature.WriteConstantString ((string) value);
- break;
- default:
- signature.WriteConstantPrimitive (value);
- break;
- }
- return signature;
- }
- SignatureWriter GetCustomAttributeSignature (CustomAttribute attribute)
- {
- var signature = CreateSignatureWriter ();
- if (!attribute.resolved) {
- signature.WriteBytes (attribute.GetBlob ());
- return signature;
- }
- signature.WriteUInt16 (0x0001);
- signature.WriteCustomAttributeConstructorArguments (attribute);
- signature.WriteCustomAttributeNamedArguments (attribute);
- return signature;
- }
- SignatureWriter GetSecurityDeclarationSignature (SecurityDeclaration declaration)
- {
- var signature = CreateSignatureWriter ();
- if (!declaration.resolved)
- signature.WriteBytes (declaration.GetBlob ());
- else if (module.Runtime < TargetRuntime.Net_2_0)
- signature.WriteXmlSecurityDeclaration (declaration);
- else
- signature.WriteSecurityDeclaration (declaration);
- return signature;
- }
- SignatureWriter GetMarshalInfoSignature (IMarshalInfoProvider owner)
- {
- var signature = CreateSignatureWriter ();
- signature.WriteMarshalInfo (owner.MarshalInfo);
- return signature;
- }
- static Exception CreateForeignMemberException (MemberReference member)
- {
- return new ArgumentException (string.Format ("Member '{0}' is declared in another module and needs to be imported", member));
- }
- public MetadataToken LookupToken (IMetadataTokenProvider provider)
- {
- if (provider == null)
- throw new ArgumentNullException ();
- if (metadata_builder != null)
- return metadata_builder.LookupToken (provider);
- var member = provider as MemberReference;
- if (member == null || member.Module != module)
- throw CreateForeignMemberException (member);
- var token = provider.MetadataToken;
- switch (token.TokenType) {
- case TokenType.TypeDef:
- case TokenType.Method:
- case TokenType.Field:
- case TokenType.Event:
- case TokenType.Property:
- return token;
- case TokenType.TypeRef:
- case TokenType.TypeSpec:
- case TokenType.GenericParam:
- return GetTypeToken ((TypeReference) provider);
- case TokenType.MethodSpec:
- return GetMethodSpecToken ((MethodSpecification) provider);
- case TokenType.MemberRef:
- return GetMemberRefToken (member);
- default:
- throw new NotSupportedException ();
- }
- }
- public void AddMethodDebugInformation (MethodDebugInformation method_info)
- {
- if (method_info.HasSequencePoints)
- AddSequencePoints (method_info);
- if (method_info.Scope != null)
- AddLocalScope (method_info, method_info.Scope);
- if (method_info.StateMachineKickOffMethod != null)
- AddStateMachineMethod (method_info);
- AddCustomDebugInformations (method_info.Method);
- }
- void AddStateMachineMethod (MethodDebugInformation method_info)
- {
- state_machine_method_table.AddRow (new StateMachineMethodRow (method_info.Method.MetadataToken.RID, method_info.StateMachineKickOffMethod.MetadataToken.RID));
- }
- void AddLocalScope (MethodDebugInformation method_info, ScopeDebugInformation scope)
- {
- var rid = local_scope_table.AddRow (new LocalScopeRow (
- method_info.Method.MetadataToken.RID,
- scope.import != null ? AddImportScope (scope.import) : 0,
- local_variable_rid,
- local_constant_rid,
- (uint) scope.Start.Offset,
- (uint) ((scope.End.IsEndOfMethod ? method_info.code_size : scope.End.Offset) - scope.Start.Offset)));
- scope.token = new MetadataToken (TokenType.LocalScope, rid);
- AddCustomDebugInformations (scope);
- if (scope.HasVariables)
- AddLocalVariables (scope);
- if (scope.HasConstants)
- AddLocalConstants (scope);
- for (int i = 0; i < scope.Scopes.Count; i++)
- AddLocalScope (method_info, scope.Scopes [i]);
- }
- void AddLocalVariables (ScopeDebugInformation scope)
- {
- for (int i = 0; i < scope.Variables.Count; i++) {
- var variable = scope.Variables [i];
- local_variable_table.AddRow (new LocalVariableRow (variable.Attributes, (ushort) variable.Index, GetStringIndex (variable.Name)));
- variable.token = new MetadataToken (TokenType.LocalVariable, local_variable_rid);
- local_variable_rid++;
- AddCustomDebugInformations (variable);
- }
- }
- void AddLocalConstants (ScopeDebugInformation scope)
- {
- for (int i = 0; i < scope.Constants.Count; i++) {
- var constant = scope.Constants [i];
- local_constant_table.AddRow (new LocalConstantRow (GetStringIndex (constant.Name), GetBlobIndex (GetConstantSignature(constant))));
- constant.token = new MetadataToken (TokenType.LocalConstant, local_constant_rid);
- local_constant_rid++;
- }
- }
- SignatureWriter GetConstantSignature (ConstantDebugInformation constant)
- {
- var type = constant.ConstantType;
- var signature = CreateSignatureWriter ();
- signature.WriteTypeSignature (type);
- if (type.IsTypeOf ("System", "Decimal")) {
- var bits = decimal.GetBits ((decimal) constant.Value);
- var low = (uint) bits [0];
- var mid = (uint) bits [1];
- var high = (uint) bits [2];
- var scale = (byte) (bits [3] >> 16);
- var negative = (bits [3] & 0x80000000) != 0;
- signature.WriteByte ((byte) (scale | (negative ? 0x80 : 0x00)));
- signature.WriteUInt32 (low);
- signature.WriteUInt32 (mid);
- signature.WriteUInt32 (high);
- return signature;
- }
- if (type.IsTypeOf ("System", "DateTime")) {
- var date = (DateTime) constant.Value;
- signature.WriteInt64 (date.Ticks);
- return signature;
- }
- signature.WriteBytes (GetConstantSignature (type.etype, constant.Value));
- return signature;
- }
- public void AddCustomDebugInformations (ICustomDebugInformationProvider provider)
- {
- if (!provider.HasCustomDebugInformations)
- return;
- var custom_infos = provider.CustomDebugInformations;
- for (int i = 0; i < custom_infos.Count; i++) {
- var custom_info = custom_infos [i];
- switch (custom_info.Kind) {
- case CustomDebugInformationKind.Binary:
- var binary_info = (BinaryCustomDebugInformation) custom_info;
- AddCustomDebugInformation (provider, binary_info, GetBlobIndex (binary_info.Data));
- break;
- case CustomDebugInformationKind.AsyncMethodBody:
- AddAsyncMethodBodyDebugInformation (provider, (AsyncMethodBodyDebugInformation) custom_info);
- break;
- case CustomDebugInformationKind.StateMachineScope:
- AddStateMachineScopeDebugInformation (provider, (StateMachineScopeDebugInformation) custom_info);
- break;
- case CustomDebugInformationKind.EmbeddedSource:
- AddEmbeddedSourceDebugInformation (provider, (EmbeddedSourceDebugInformation) custom_info);
- break;
- case CustomDebugInformationKind.SourceLink:
- AddSourceLinkDebugInformation (provider, (SourceLinkDebugInformation) custom_info);
- break;
- default:
- throw new NotImplementedException ();
- }
- }
- }
- void AddStateMachineScopeDebugInformation (ICustomDebugInformationProvider provider, StateMachineScopeDebugInformation state_machine_scope)
- {
- var method_info = ((MethodDefinition) provider).DebugInformation;
- var signature = CreateSignatureWriter ();
- var scopes = state_machine_scope.Scopes;
- for (int i = 0; i < scopes.Count; i++) {
- var scope = scopes [i];
- signature.WriteUInt32 ((uint) scope.Start.Offset);
- var end_offset = scope.End.IsEndOfMethod
- ? method_info.code_size
- : scope.End.Offset;
- signature.WriteUInt32 ((uint) (end_offset - scope.Start.Offset));
- }
- AddCustomDebugInformation (provider, state_machine_scope, signature);
- }
- void AddAsyncMethodBodyDebugInformation (ICustomDebugInformationProvider provider, AsyncMethodBodyDebugInformation async_method)
- {
- var signature = CreateSignatureWriter ();
- signature.WriteUInt32 ((uint) async_method.catch_handler.Offset + 1);
- if (!async_method.yields.IsNullOrEmpty ()) {
- for (int i = 0; i < async_method.yields.Count; i++) {
- signature.WriteUInt32 ((uint) async_method.yields [i].Offset);
- signature.WriteUInt32 ((uint) async_method.resumes [i].Offset);
- signature.WriteCompressedUInt32 (async_method.resume_methods [i].MetadataToken.RID);
- }
- }
- AddCustomDebugInformation (provider, async_method, signature);
- }
- void AddEmbeddedSourceDebugInformation (ICustomDebugInformationProvider provider, EmbeddedSourceDebugInformation embedded_source)
- {
- var signature = CreateSignatureWriter ();
- var content = embedded_source.content ?? Empty<byte>.Array;
- if (embedded_source.compress) {
- signature.WriteInt32 (content.Length);
- var decompressed_stream = new MemoryStream (content);
- var content_stream = new MemoryStream ();
- using (var compress_stream = new DeflateStream (content_stream, CompressionMode.Compress, leaveOpen: true))
- decompressed_stream.CopyTo (compress_stream);
- signature.WriteBytes (content_stream.ToArray ());
- } else {
- signature.WriteInt32 (0);
- signature.WriteBytes (content);
- }
- AddCustomDebugInformation (provider, embedded_source, signature);
- }
- void AddSourceLinkDebugInformation (ICustomDebugInformationProvider provider, SourceLinkDebugInformation source_link)
- {
- var signature = CreateSignatureWriter ();
- signature.WriteBytes (Encoding.UTF8.GetBytes (source_link.content));
- AddCustomDebugInformation (provider, source_link, signature);
- }
- void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, SignatureWriter signature)
- {
- AddCustomDebugInformation (provider, custom_info, GetBlobIndex (signature));
- }
- void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, uint blob_index)
- {
- var rid = custom_debug_information_table.AddRow (new CustomDebugInformationRow (
- MakeCodedRID (provider.MetadataToken, CodedIndex.HasCustomDebugInformation),
- GetGuidIndex (custom_info.Identifier),
- blob_index));
- custom_info.token = new MetadataToken (TokenType.CustomDebugInformation, rid);
- }
- uint AddImportScope (ImportDebugInformation import)
- {
- uint parent = 0;
- if (import.Parent != null)
- parent = AddImportScope (import.Parent);
- uint targets_index = 0;
- if (import.HasTargets) {
- var signature = CreateSignatureWriter ();
- for (int i = 0; i < import.Targets.Count; i++)
- AddImportTarget (import.Targets [i], signature);
- targets_index = GetBlobIndex (signature);
- }
- var row = new ImportScopeRow (parent, targets_index);
- MetadataToken import_token;
- if (import_scope_map.TryGetValue (row, out import_token))
- return import_token.RID;
- import_token = new MetadataToken (TokenType.ImportScope, import_scope_table.AddRow (row));
- import_scope_map.Add (row, import_token);
- return import_token.RID;
- }
- void AddImportTarget (ImportTarget target, SignatureWriter signature)
- {
- signature.WriteCompressedUInt32 ((uint)target.kind);
- switch (target.kind) {
- case ImportTargetKind.ImportNamespace:
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
- break;
- case ImportTargetKind.ImportNamespaceInAssembly:
- signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID);
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
- break;
- case ImportTargetKind.ImportType:
- signature.WriteTypeToken (target.type);
- break;
- case ImportTargetKind.ImportXmlNamespaceWithAlias:
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
- break;
- case ImportTargetKind.ImportAlias:
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
- break;
- case ImportTargetKind.DefineAssemblyAlias:
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
- signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID);
- break;
- case ImportTargetKind.DefineNamespaceAlias:
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
- break;
- case ImportTargetKind.DefineNamespaceInAssemblyAlias:
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
- signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID);
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
- break;
- case ImportTargetKind.DefineTypeAlias:
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
- signature.WriteTypeToken (target.type);
- break;
- }
- }
- uint GetUTF8StringBlobIndex (string s)
- {
- return GetBlobIndex (Encoding.UTF8.GetBytes (s));
- }
- public MetadataToken GetDocumentToken (Document document)
- {
- MetadataToken token;
- if (document_map.TryGetValue (document.Url, out token))
- return token;
- token = new MetadataToken (TokenType.Document, document_table.AddRow (
- new DocumentRow (GetBlobIndex (GetDocumentNameSignature (document)),
- GetGuidIndex (document.HashAlgorithm.ToGuid ()),
- GetBlobIndex (document.Hash),
- GetGuidIndex (document.Language.ToGuid ()))));
- document.token = token;
- AddCustomDebugInformations (document);
- document_map.Add (document.Url, token);
- return token;
- }
- SignatureWriter GetDocumentNameSignature (Document document)
- {
- var name = document.Url;
- var signature = CreateSignatureWriter ();
- char separator;
- if (!TryGetDocumentNameSeparator (name, out separator)) {
- signature.WriteByte (0);
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (name));
- return signature;
- }
- signature.WriteByte ((byte) separator);
- var parts = name.Split (new [] { separator });
- for (int i = 0; i < parts.Length; i++) {
- if (parts [i] == String.Empty)
- signature.WriteCompressedUInt32 (0);
- else
- signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (parts [i]));
- }
- return signature;
- }
- static bool TryGetDocumentNameSeparator (string path, out char separator)
- {
- const char unix = '/';
- const char win = '\\';
- const char zero = (char) 0;
- separator = zero;
- if (string.IsNullOrEmpty (path))
- return false;
- int unix_count = 0;
- int win_count = 0;
- for (int i = 0; i < path.Length; i++) {
- if (path [i] == unix)
- unix_count++;
- else if (path [i] == win)
- win_count++;
- }
- if (unix_count == 0 && win_count == 0)
- return false;
- if (unix_count >= win_count) {
- separator = unix;
- return true;
- }
- separator = win;
- return true;
- }
- void AddSequencePoints (MethodDebugInformation info)
- {
- var rid = info.Method.MetadataToken.RID;
- Document document;
- if (info.TryGetUniqueDocument (out document))
- method_debug_information_table.rows [rid - 1].Col1 = GetDocumentToken (document).RID;
- var signature = CreateSignatureWriter ();
- signature.WriteSequencePoints (info);
- method_debug_information_table.rows [rid - 1].Col2 = GetBlobIndex (signature);
- }
- }
- sealed class SignatureWriter : ByteBuffer {
- readonly MetadataBuilder metadata;
- public SignatureWriter (MetadataBuilder metadata)
- : base (6)
- {
- this.metadata = metadata;
- }
- public void WriteElementType (ElementType element_type)
- {
- WriteByte ((byte) element_type);
- }
- public void WriteUTF8String (string @string)
- {
- if (@string == null) {
- WriteByte (0xff);
- return;
- }
- var bytes = Encoding.UTF8.GetBytes (@string);
- WriteCompressedUInt32 ((uint) bytes.Length);
- WriteBytes (bytes);
- }
- public void WriteMethodSignature (IMethodSignature method)
- {
- byte calling_convention = (byte) method.CallingConvention;
- if (method.HasThis)
- calling_convention |= 0x20;
- if (method.ExplicitThis)
- calling_convention |= 0x40;
- var generic_provider = method as IGenericParameterProvider;
- var generic_arity = generic_provider != null && generic_provider.HasGenericParameters
- ? generic_provider.GenericParameters.Count
- : 0;
- if (generic_arity > 0)
- calling_convention |= 0x10;
- var param_count = method.HasParameters ? method.Parameters.Count : 0;
- WriteByte (calling_convention);
- if (generic_arity > 0)
- WriteCompressedUInt32 ((uint) generic_arity);
- WriteCompressedUInt32 ((uint) param_count);
- WriteTypeSignature (method.ReturnType);
- if (param_count == 0)
- return;
- var parameters = method.Parameters;
- for (int i = 0; i < param_count; i++)
- WriteTypeSignature (parameters [i].ParameterType);
- }
- uint MakeTypeDefOrRefCodedRID (TypeReference type)
- {
- return CodedIndex.TypeDefOrRef.CompressMetadataToken (metadata.LookupToken (type));
- }
- public void WriteTypeToken (TypeReference type)
- {
- WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type));
- }
- public void WriteTypeSignature (TypeReference type)
- {
- if (type == null)
- throw new ArgumentNullException ();
- var etype = type.etype;
- switch (etype) {
- case ElementType.MVar:
- case ElementType.Var: {
- var generic_parameter = (GenericParameter) type;
- WriteElementType (etype);
- var position = generic_parameter.Position;
- if (position == -1)
- throw new NotSupportedException ();
- WriteCompressedUInt32 ((uint) position);
- break;
- }
- case ElementType.GenericInst: {
- var generic_instance = (GenericInstanceType) type;
- WriteElementType (ElementType.GenericInst);
- WriteElementType (generic_instance.IsValueType ? ElementType.ValueType : ElementType.Class);
- WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (generic_instance.ElementType));
- WriteGenericInstanceSignature (generic_instance);
- break;
- }
- case ElementType.Ptr:
- case ElementType.ByRef:
- case ElementType.Pinned:
- case ElementType.Sentinel: {
- var type_spec = (TypeSpecification) type;
- WriteElementType (etype);
- WriteTypeSignature (type_spec.ElementType);
- break;
- }
- case ElementType.FnPtr: {
- var fptr = (FunctionPointerType) type;
- WriteElementType (ElementType.FnPtr);
- WriteMethodSignature (fptr);
- break;
- }
- case ElementType.CModOpt:
- case ElementType.CModReqD: {
- var modifier = (IModifierType) type;
- WriteModifierSignature (etype, modifier);
- break;
- }
- case ElementType.Array: {
- var array = (ArrayType) type;
- if (!array.IsVector) {
- WriteArrayTypeSignature (array);
- break;
- }
- WriteElementType (ElementType.SzArray);
- WriteTypeSignature (array.ElementType);
- break;
- }
- case ElementType.None: {
- WriteElementType (type.IsValueType ? ElementType.ValueType : ElementType.Class);
- WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type));
- break;
- }
- default:
- if (!TryWriteElementType (type))
- throw new NotSupportedException ();
- break;
- }
- }
- void WriteArrayTypeSignature (ArrayType array)
- {
- WriteElementType (ElementType.Array);
- WriteTypeSignature (array.ElementType);
- var dimensions = array.Dimensions;
- var rank = dimensions.Count;
- WriteCompressedUInt32 ((uint) rank);
- var sized = 0;
- var lbounds = 0;
- for (int i = 0; i < rank; i++) {
- var dimension = dimensions [i];
- if (dimension.UpperBound.HasValue) {
- sized++;
- lbounds++;
- } else if (dimension.LowerBound.HasValue)
- lbounds++;
- }
- var sizes = new int [sized];
- var low_bounds = new int [lbounds];
- for (int i = 0; i < lbounds; i++) {
- var dimension = dimensions [i];
- low_bounds [i] = dimension.LowerBound.GetValueOrDefault ();
- if (dimension.UpperBound.HasValue)
- sizes [i] = dimension.UpperBound.Value - low_bounds [i] + 1;
- }
- WriteCompressedUInt32 ((uint) sized);
- for (int i = 0; i < sized; i++)
- WriteCompressedUInt32 ((uint) sizes [i]);
- WriteCompressedUInt32 ((uint) lbounds);
- for (int i = 0; i < lbounds; i++)
- WriteCompressedInt32 (low_bounds [i]);
- }
- public void WriteGenericInstanceSignature (IGenericInstance instance)
- {
- var generic_arguments = instance.GenericArguments;
- var arity = generic_arguments.Count;
- WriteCompressedUInt32 ((uint) arity);
- for (int i = 0; i < arity; i++)
- WriteTypeSignature (generic_arguments [i]);
- }
- void WriteModifierSignature (ElementType element_type, IModifierType type)
- {
- WriteElementType (element_type);
- WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type.ModifierType));
- WriteTypeSignature (type.ElementType);
- }
- bool TryWriteElementType (TypeReference type)
- {
- var element = type.etype;
- if (element == ElementType.None)
- return false;
- WriteElementType (element);
- return true;
- }
- public void WriteConstantString (string value)
- {
- if (value != null)
- WriteBytes (Encoding.Unicode.GetBytes (value));
- else
- WriteByte (0xff);
- }
- public void WriteConstantPrimitive (object value)
- {
- WritePrimitiveValue (value);
- }
- public void WriteCustomAttributeConstructorArguments (CustomAttribute attribute)
- {
- if (!attribute.HasConstructorArguments)
- return;
- var arguments = attribute.ConstructorArguments;
- var parameters = attribute.Constructor.Parameters;
- if (parameters.Count != arguments.Count)
- throw new InvalidOperationException ();
- for (int i = 0; i < arguments.Count; i++)
- WriteCustomAttributeFixedArgument (parameters [i].ParameterType, arguments [i]);
- }
- void WriteCustomAttributeFixedArgument (TypeReference type, CustomAttributeArgument argument)
- {
- if (type.IsArray) {
- WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument);
- return;
- }
- WriteCustomAttributeElement (type, argument);
- }
- void WriteCustomAttributeFixedArrayArgument (ArrayType type, CustomAttributeArgument argument)
- {
- var values = argument.Value as CustomAttributeArgument [];
- if (values == null) {
- WriteUInt32 (0xffffffff);
- return;
- }
- WriteInt32 (values.Length);
- if (values.Length == 0)
- return;
- var element_type = type.ElementType;
- for (int i = 0; i < values.Length; i++)
- WriteCustomAttributeElement (element_type, values [i]);
- }
- void WriteCustomAttributeElement (TypeReference type, CustomAttributeArgument argument)
- {
- if (type.IsArray) {
- WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument);
- return;
- }
- if (type.etype == ElementType.Object) {
- argument = (CustomAttributeArgument) argument.Value;
- type = argument.Type;
- WriteCustomAttributeFieldOrPropType (type);
- WriteCustomAttributeElement (type, argument);
- return;
- }
- WriteCustomAttributeValue (type, argument.Value);
- }
- void WriteCustomAttributeValue (TypeReference type, object value)
- {
- var etype = type.etype;
- switch (etype) {
- case ElementType.String:
- var @string = (string) value;
- if (@string == null)
- WriteByte (0xff);
- else
- WriteUTF8String (@string);
- break;
- case ElementType.None:
- if (type.IsTypeOf ("System", "Type"))
- WriteTypeReference ((TypeReference) value);
- else
- WriteCustomAttributeEnumValue (type, value);
- break;
- default:
- WritePrimitiveValue (value);
- break;
- }
- }
- void WritePrimitiveValue (object value)
- {
- if (value == null)
- throw new ArgumentNullException ();
- switch (value.GetType ().GetTypeCode ()) {
- case TypeCode.Boolean:
- WriteByte ((byte) (((bool) value) ? 1 : 0));
- break;
- case TypeCode.Byte:
- WriteByte ((byte) value);
- break;
- case TypeCode.SByte:
- WriteSByte ((sbyte) value);
- break;
- case TypeCode.Int16:
- WriteInt16 ((short) value);
- break;
- case TypeCode.UInt16:
- WriteUInt16 ((ushort) value);
- break;
- case TypeCode.Char:
- WriteInt16 ((short) (char) value);
- break;
- case TypeCode.Int32:
- WriteInt32 ((int) value);
- break;
- case TypeCode.UInt32:
- WriteUInt32 ((uint) value);
- break;
- case TypeCode.Single:
- WriteSingle ((float) value);
- break;
- case TypeCode.Int64:
- WriteInt64 ((long) value);
- break;
- case TypeCode.UInt64:
- WriteUInt64 ((ulong) value);
- break;
- case TypeCode.Double:
- WriteDouble ((double) value);
- break;
- default:
- throw new NotSupportedException (value.GetType ().FullName);
- }
- }
- void WriteCustomAttributeEnumValue (TypeReference enum_type, object value)
- {
- var type = enum_type.CheckedResolve ();
- if (!type.IsEnum)
- throw new ArgumentException ();
- WriteCustomAttributeValue (type.GetEnumUnderlyingType (), value);
- }
- void WriteCustomAttributeFieldOrPropType (TypeReference type)
- {
- if (type.IsArray) {
- var array = (ArrayType) type;
- WriteElementType (ElementType.SzArray);
- WriteCustomAttributeFieldOrPropType (array.ElementType);
- return;
- }
- var etype = type.etype;
- switch (etype) {
- case ElementType.Object:
- WriteElementType (ElementType.Boxed);
- return;
- case ElementType.None:
- if (type.IsTypeOf ("System", "Type"))
- WriteElementType (ElementType.Type);
- else {
- WriteElementType (ElementType.Enum);
- WriteTypeReference (type);
- }
- return;
- default:
- WriteElementType (etype);
- return;
- }
- }
- public void WriteCustomAttributeNamedArguments (CustomAttribute attribute)
- {
- var count = GetNamedArgumentCount (attribute);
- WriteUInt16 ((ushort) count);
- if (count == 0)
- return;
- WriteICustomAttributeNamedArguments (attribute);
- }
- static int GetNamedArgumentCount (ICustomAttribute attribute)
- {
- int count = 0;
- if (attribute.HasFields)
- count += attribute.Fields.Count;
- if (attribute.HasProperties)
- count += attribute.Properties.Count;
- return count;
- }
- void WriteICustomAttributeNamedArguments (ICustomAttribute attribute)
- {
- if (attribute.HasFields)
- WriteCustomAttributeNamedArguments (0x53, attribute.Fields);
- if (attribute.HasProperties)
- WriteCustomAttributeNamedArguments (0x54, attribute.Properties);
- }
- void WriteCustomAttributeNamedArguments (byte kind, Collection<CustomAttributeNamedArgument> named_arguments)
- {
- for (int i = 0; i < named_arguments.Count; i++)
- WriteCustomAttributeNamedArgument (kind, named_arguments [i]);
- }
- void WriteCustomAttributeNamedArgument (byte kind, CustomAttributeNamedArgument named_argument)
- {
- var argument = named_argument.Argument;
- WriteByte (kind);
- WriteCustomAttributeFieldOrPropType (argument.Type);
- WriteUTF8String (named_argument.Name);
- WriteCustomAttributeFixedArgument (argument.Type, argument);
- }
- void WriteSecurityAttribute (SecurityAttribute attribute)
- {
- WriteTypeReference (attribute.AttributeType);
- var count = GetNamedArgumentCount (attribute);
- if (count == 0) {
- WriteCompressedUInt32 (1); // length
- WriteCompressedUInt32 (0); // count
- return;
- }
- var buffer = new SignatureWriter (metadata);
- buffer.WriteCompressedUInt32 ((uint) count);
- buffer.WriteICustomAttributeNamedArguments (attribute);
- WriteCompressedUInt32 ((uint) buffer.length);
- WriteBytes (buffer);
- }
- public void WriteSecurityDeclaration (SecurityDeclaration declaration)
- {
- WriteByte ((byte) '.');
- var attributes = declaration.security_attributes;
- if (attributes == null)
- throw new NotSupportedException ();
- WriteCompressedUInt32 ((uint) attributes.Count);
- for (int i = 0; i < attributes.Count; i++)
- WriteSecurityAttribute (attributes [i]);
- }
- public void WriteXmlSecurityDeclaration (SecurityDeclaration declaration)
- {
- var xml = GetXmlSecurityDeclaration (declaration);
- if (xml == null)
- throw new NotSupportedException ();
- WriteBytes (Encoding.Unicode.GetBytes (xml));
- }
- static string GetXmlSecurityDeclaration (SecurityDeclaration declaration)
- {
- if (declaration.security_attributes == null || declaration.security_attributes.Count != 1)
- return null;
- var attribute = declaration.security_attributes [0];
- if (!attribute.AttributeType.IsTypeOf ("System.Security.Permissions", "PermissionSetAttribute"))
- return null;
- if (attribute.properties == null || attribute.properties.Count != 1)
- return null;
- var property = attribute.properties [0];
- if (property.Name != "XML")
- return null;
- return (string) property.Argument.Value;
- }
- void WriteTypeReference (TypeReference type)
- {
- WriteUTF8String (TypeParser.ToParseable (type, top_level: false));
- }
- public void WriteMarshalInfo (MarshalInfo marshal_info)
- {
- WriteNativeType (marshal_info.native);
- switch (marshal_info.native) {
- case NativeType.Array: {
- var array = (ArrayMarshalInfo) marshal_info;
- if (array.element_type != NativeType.None)
- WriteNativeType (array.element_type);
- if (array.size_parameter_index > -1)
- WriteCompressedUInt32 ((uint) array.size_parameter_index);
- if (array.size > -1)
- WriteCompressedUInt32 ((uint) array.size);
- if (array.size_parameter_multiplier > -1)
- WriteCompressedUInt32 ((uint) array.size_parameter_multiplier);
- return;
- }
- case NativeType.SafeArray: {
- var array = (SafeArrayMarshalInfo) marshal_info;
- if (array.element_type != VariantType.None)
- WriteVariantType (array.element_type);
- return;
- }
- case NativeType.FixedArray: {
- var array = (FixedArrayMarshalInfo) marshal_info;
- if (array.size > -1)
- WriteCompressedUInt32 ((uint) array.size);
- if (array.element_type != NativeType.None)
- WriteNativeType (array.element_type);
- return;
- }
- case NativeType.FixedSysString:
- var sys_string = (FixedSysStringMarshalInfo) marshal_info;
- if (sys_string.size > -1)
- WriteCompressedUInt32 ((uint) sys_string.size);
- return;
- case NativeType.CustomMarshaler:
- var marshaler = (CustomMarshalInfo) marshal_info;
- WriteUTF8String (marshaler.guid != Guid.Empty ? marshaler.guid.ToString () : string.Empty);
- WriteUTF8String (marshaler.unmanaged_type);
- WriteTypeReference (marshaler.managed_type);
- WriteUTF8String (marshaler.cookie);
- return;
- }
- }
- void WriteNativeType (NativeType native)
- {
- WriteByte ((byte) native);
- }
- void WriteVariantType (VariantType variant)
- {
- WriteByte ((byte) variant);
- }
- public void WriteSequencePoints (MethodDebugInformation info)
- {
- var start_line = -1;
- var start_column = -1;
- WriteCompressedUInt32 (info.local_var_token.RID);
- Document previous_document;
- if (!info.TryGetUniqueDocument (out previous_document))
- previous_document = null;
- for (int i = 0; i < info.SequencePoints.Count; i++) {
- var sequence_point = info.SequencePoints [i];
- var document = sequence_point.Document;
- if (previous_document != document) {
- var document_token = metadata.GetDocumentToken (document);
- if (previous_document != null)
- WriteCompressedUInt32 (0);
- WriteCompressedUInt32 (document_token.RID);
- previous_document = document;
- }
- if (i > 0)
- WriteCompressedUInt32 ((uint) (sequence_point.Offset - info.SequencePoints [i - 1].Offset));
- else
- WriteCompressedUInt32 ((uint) sequence_point.Offset);
- if (sequence_point.IsHidden) {
- WriteInt16 (0);
- continue;
- }
- var delta_lines = sequence_point.EndLine - sequence_point.StartLine;
- var delta_columns = sequence_point.EndColumn - sequence_point.StartColumn;
- WriteCompressedUInt32 ((uint) delta_lines);
- if (delta_lines == 0)
- WriteCompressedUInt32((uint) delta_columns);
- else
- WriteCompressedInt32 (delta_columns);
- if (start_line < 0) {
- WriteCompressedUInt32 ((uint) sequence_point.StartLine);
- WriteCompressedUInt32 ((uint) sequence_point.StartColumn);
- } else {
- WriteCompressedInt32 (sequence_point.StartLine - start_line);
- WriteCompressedInt32 (sequence_point.StartColumn - start_column);
- }
- start_line = sequence_point.StartLine;
- start_column = sequence_point.StartColumn;
- }
- }
- }
- #endif
- static partial class Mixin {
- public static bool TryGetUniqueDocument (this MethodDebugInformation info, out Document document)
- {
- document = info.SequencePoints [0].Document;
- for (int i = 1; i < info.SequencePoints.Count; i++) {
- var sequence_point = info.SequencePoints [i];
- if (sequence_point.Document != document)
- return false;
- }
- return true;
- }
- }
- }
|