From ec65da1fbc93bd4fcdbdf20cb41c085ece53473c Mon Sep 17 00:00:00 2001 From: aszlig Date: Wed, 18 Jul 2018 11:47:03 +0200 Subject: monogame-patcher: Allow specifying extra assembly If we want to replace a call with one that's not in a module which is currently referenced by the target file we now have another command line flag for replace-call (-a) where we can specify the additional DLL file. Signed-off-by: aszlig --- .../build-support/monogame-patcher/src/options.cs | 4 ++ .../build-support/monogame-patcher/src/patcher.cs | 47 +++++++++++++++------- .../build-support/monogame-patcher/src/test.sh | 21 ++++++++++ 3 files changed, 58 insertions(+), 14 deletions(-) (limited to 'pkgs/games/build-support') diff --git a/pkgs/games/build-support/monogame-patcher/src/options.cs b/pkgs/games/build-support/monogame-patcher/src/options.cs index 32a8403e..73add8d6 100644 --- a/pkgs/games/build-support/monogame-patcher/src/options.cs +++ b/pkgs/games/build-support/monogame-patcher/src/options.cs @@ -27,4 +27,8 @@ class ReplaceCallCmd : GenericOptions { [Value(2, Required=true, MetaName = "type", HelpText = "Types to patch.")] public IEnumerable typesToPatch { get; set; } + + [Option('a', "assembly", + HelpText="Look up replacement from the specified assembly.")] + public string assemblyFile { get; set; } }; diff --git a/pkgs/games/build-support/monogame-patcher/src/patcher.cs b/pkgs/games/build-support/monogame-patcher/src/patcher.cs index 6aeaa324..961a6b7e 100644 --- a/pkgs/games/build-support/monogame-patcher/src/patcher.cs +++ b/pkgs/games/build-support/monogame-patcher/src/patcher.cs @@ -21,28 +21,36 @@ class Command { this.outfile = options.outputFile; this.infile = options.inputFile; + var readOnly = this.infile != this.outfile; + this.module = this.read_module(this.infile, readOnly); + } + + protected ModuleDefinition read_module(string path, bool readOnly) { var resolver = new DefaultAssemblyResolver(); - resolver.AddSearchDirectory(Path.GetDirectoryName(this.infile)); + resolver.AddSearchDirectory(Path.GetDirectoryName(path)); var rp = new ReaderParameters { - ReadWrite = this.infile == this.outfile, + ReadWrite = !readOnly, AssemblyResolver = resolver }; - this.module = ModuleDefinition.ReadModule(this.infile, rp); + return ModuleDefinition.ReadModule(path, rp); + } + + protected virtual IEnumerable get_assembly_types() { + return this.module.AssemblyReferences + .Select(a => this.module.AssemblyResolver.Resolve(a)) + .SelectMany(r => r.MainModule.Types); } protected MethodReference find_method_ref(string fullSig) { - foreach (var aref in this.module.AssemblyReferences) { - var resolved = this.module.AssemblyResolver.Resolve(aref); - foreach (var type in resolved.MainModule.Types) { - foreach (var ctor in type.GetConstructors()) { - if (ctor.ToString() != fullSig) continue; - return this.module.ImportReference(ctor); - } - foreach (var meth in type.GetMethods()) { - if (meth.ToString() != fullSig) continue; - return this.module.ImportReference(meth); - } + foreach (var type in this.get_assembly_types()) { + foreach (var ctor in type.GetConstructors()) { + if (ctor.ToString() != fullSig) continue; + return this.module.ImportReference(ctor); + } + foreach (var meth in type.GetMethods()) { + if (meth.ToString() != fullSig) continue; + return this.module.ImportReference(meth); } } @@ -99,8 +107,12 @@ class FixFileStreams : Command { class ReplaceCall : Command { private string search; private MethodReference replace; + private ModuleDefinition targetModule; public ReplaceCall(ReplaceCallCmd options) : base(options) { + if (options.assemblyFile != null) + this.targetModule = this.read_module(options.assemblyFile, true); + this.search = options.replaceMethod; this.replace = this.find_method_ref(options.replacementMethod); @@ -113,6 +125,13 @@ class ReplaceCall : Command { this.save(); } + protected override IEnumerable get_assembly_types() { + if (this.targetModule != null) + return this.targetModule.Types; + else + return base.get_assembly_types(); + } + private void patch_method(MethodDefinition md) { var il = md.Body.GetILProcessor(); diff --git a/pkgs/games/build-support/monogame-patcher/src/test.sh b/pkgs/games/build-support/monogame-patcher/src/test.sh index b19457d4..a4f65aef 100644 --- a/pkgs/games/build-support/monogame-patcher/src/test.sh +++ b/pkgs/games/build-support/monogame-patcher/src/test.sh @@ -34,6 +34,19 @@ public class b { } EOF +cat > "c.cs" < "test1.cs" < write_test.txt test "$(mono subdir/test2.exe)" = "can write" -- cgit 1.4.1