summaryrefslogtreecommitdiff
path: root/BCT/BytecodeTranslator/Program.cs
blob: c1875b97a6f40f8d6d468f1856e32cd525612c4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation.  All Rights Reserved.
//
//-----------------------------------------------------------------------------

using System;
using System.IO;
using Microsoft.Cci;
using Microsoft.Cci.MetadataReader;
using Microsoft.Cci.MutableCodeModel;
using System.Collections.Generic;
using Microsoft.Cci.Contracts;
using Microsoft.Cci.ILToCodeModel;

using Bpl = Microsoft.Boogie;

namespace BytecodeTranslator {
  public class CommandLineOptions
  {
    public static bool SplitFields = false;
  }

  public class BCT {

    public static IMetadataHost Host;

    public static bool Parse(string[] args, out string assemblyName)
    {
        assemblyName = "";
        
        foreach (string arg in args)
        {
            if (arg.StartsWith("/"))
            {
                if (arg == "/splitFields")
                {
                    CommandLineOptions.SplitFields = true;
                }
                else
                {
                    Console.WriteLine("Illegal option.");
                    return false;
                }
            }
            else if (assemblyName == "")
            {
                assemblyName = arg;
            }
            else
            {
                Console.WriteLine("Must specify only one input assembly.");
                return false;
            }
        }
        if (assemblyName == "")
        {
            Console.WriteLine("Must specify an input assembly.");
            return false;
        }
        return true;
    }

    static int Main(string[] args)
    {
      int result = 0;
      string assemblyName;
      if (!Parse(args, out assemblyName))
          return result;
      try {
        result = DoRealWork(assemblyName);
      } catch (Exception e) { // swallow everything and just return an error code
        Console.WriteLine("The byte-code translator failed with uncaught exception: {0}", e.Message);
        Console.WriteLine("Stack trace: {0}", e.StackTrace);
        return -1;
      }
      return result;
    }

    static int DoRealWork(string assemblyName) {

      var host = new Microsoft.Cci.MutableContracts.CodeContractAwareHostEnvironment();
      Host = host;

      IModule/*?*/ module = host.LoadUnitFrom(assemblyName) as IModule;
      if (module == null || module == Dummy.Module || module == Dummy.Assembly) {
        Console.WriteLine(assemblyName + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
        return 1;
      }

      IAssembly/*?*/ assembly = null;

      PdbReader/*?*/ pdbReader = null;
      string pdbFile = Path.ChangeExtension(module.Location, "pdb");
      if (File.Exists(pdbFile)) {
        Stream pdbStream = File.OpenRead(pdbFile);
        pdbReader = new PdbReader(pdbStream, host);
      }

      module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader);

      #region Pass 3: Translate the code model to BPL
      //tmp_BPLGenerator translator = new tmp_BPLGenerator(host, acp);
      var factory = new CLRSemantics();
      MetadataTraverser translator = factory.MakeMetadataTraverser(host.GetContractExtractor(module.ModuleIdentity));
      assembly = module as IAssembly;
      if (assembly != null)
        translator.Visit(assembly);
      else
        translator.Visit(module);
      #endregion Pass 3: Translate the code model to BPL
      Microsoft.Boogie.TokenTextWriter writer = new Microsoft.Boogie.TokenTextWriter(module.Name + ".bpl");
      Prelude.Emit(writer);
      translator.TranslatedProgram.Emit(writer);
      writer.Close();
      return 0; // success
    }

    private static string NameUpToFirstPeriod(string name) {
      var i = name.IndexOf('.');
      if (i == -1)
        return name;
      else
        return name.Substring(0, i);
    }


  }

}