Exemple #1
0
        private static void GenerateMissingMethod(string str, metadata.MetadataStream m, libtysila5.target.Target t, int missing_msig, ElfFile o, libtysila5.TysilaState s)
        {
            /* Generate new method spec */
            var ms = new metadata.MethodSpec {
                m = m, mangle_override = str
            };

            /* Generate stub code */
            libtysila5.Code c = new libtysila5.Code();
            c.t  = t;
            c.ms = ms;

            var ir      = new List <libtysila5.cil.CilNode.IRNode>();
            var stack   = new libtysila5.util.Stack <libtysila5.ir.StackItem>();
            var cilnode = new libtysila5.cil.CilNode(ms, 0);

            cilnode.irnodes = ir;
            c.ir            = ir;
            c.starts        = new List <libtysila5.cil.CilNode> {
                cilnode
            };
            c.s = s;

            stack = libtysila5.ir.ConvertToIR.ldstr(cilnode, c, stack, str);
            stack = libtysila5.ir.ConvertToIR.call(cilnode, c, stack, false, "missing_function",
                                                   c.special_meths, missing_msig);

            /* Assemble */
            libtysila5.libtysila.AssembleMethod(ms, o, t, s, null, null, c);
        }
Exemple #2
0
        internal static unsafe void *JitCompile(metadata.MethodSpec meth)
        {
            var s = InitTysilaState();

            // Add the new method to the requestor
            ((JitRequestor)s.r).FullMethodRequestor.Request(meth);

            // Compile all needed bits
            JitProcess.ProcessRequestedItems(s, Program.stab);

            // Add everything from the current state to output sections
            return(CopyToOutput(s, TextSection));    // First Method requested will be at start of Text section
        }
Exemple #3
0
        private void build_method_list()
        {
            System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosType: building method list for " + FullName);

            var t          = tspec;
            var first_mdef = ts.m.GetIntEntry(metadata.MetadataStream.tid_TypeDef, t.tdrow, 5);
            var last_mdef  = ts.m.GetLastMethodDef(t.tdrow);

            var _methods    = new TysosMethod[last_mdef - first_mdef];
            var _first_name = new Dictionary <string, int>(new metadata.GenericEqualityComparer <string>());
            var _next_name  = new int[last_mdef - first_mdef];

            for (int i = 0; i < last_mdef - first_mdef; i++)
            {
                _next_name[i] = -1;
            }

            var cur_idx = 0;

            for (var cur_mdef = first_mdef; cur_mdef < last_mdef; cur_mdef++, cur_idx++)
            {
                metadata.MethodSpec ms = new metadata.MethodSpec {
                    type = t, mdrow = (int)cur_mdef, m = t.m, msig = (int)ts.m.GetIntEntry(metadata.MetadataStream.tid_MethodDef, (int)cur_mdef, 4)
                };
                var cur_m = new TysosMethod(ms, this);
                System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosType: adding method " + cur_m.Name);
                _methods[cur_idx] = cur_m;
                if (_first_name.TryGetValue(cur_m.Name, out var fn))
                {
                    while (_next_name[fn] != -1)
                    {
                        fn = _next_name[fn];
                    }
                    _next_name[fn] = cur_idx;
                }
                else
                {
                    _first_name[cur_m.Name] = cur_idx;
                }
            }

            if (System.Threading.Interlocked.CompareExchange(ref methods, _methods, null) == null)
            {
                first_name = _first_name;
                next_name  = _next_name;
            }

            System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosType: done building method list");
        }
Exemple #4
0
        public DwarfMethodDIE GetMethodDie(metadata.MethodSpec ms)
        {
            DwarfMethodDIE ret;

            if (method_dies.TryGetValue(ms, out ret))
            {
                return(ret);
            }
            ret             = new DwarfMethodDIE();
            ret.ms          = ms;
            ret.t           = t;
            ret.dcu         = this;
            method_dies[ms] = ret;
            return(ret);
        }
Exemple #5
0
        public virtual bool IsMethodValid(metadata.MethodSpec ms)
        {
            if (!IsTypeValid(ms.type))
            {
                return(false);
            }
            if (ms.HasCustomAttribute("_ZN14libsupcs#2Edll8libsupcs19Bits32OnlyAttribute_7#2Ector_Rv_P1u1t") &&
                GetPointerSize() != 4)
            {
                return(false);
            }
            if (ms.HasCustomAttribute("_ZN14libsupcs#2Edll8libsupcs19Bits64OnlyAttribute_7#2Ector_Rv_P1u1t") &&
                GetPointerSize() != 8)
            {
                return(false);
            }

            bool is_arch_dependent = false;
            bool is_required_arch  = false;

            foreach (var idx in ms.CustomAttributes("_ZN14libsupcs#2Edll8libsupcs22ArchDependentAttribute_7#2Ector_Rv_P2u1tu1S"))
            {
                var sig_idx = ms.m.GetCustomAttrSigIdx(idx);
                var arch    = ms.m.ReadCustomAttrString(ref sig_idx);
                is_arch_dependent = true;
                if (arch.Equals(name))
                {
                    is_required_arch = true;
                }
            }

            if (is_arch_dependent && !is_required_arch)
            {
                return(false);
            }

            return(true);
        }
Exemple #6
0
 public TysosMethod(metadata.MethodSpec ms, TysosType owning_type)
 {
     mspec      = ms;
     OwningType = owning_type;
 }
Exemple #7
0
        static internal Code ParseCIL(metadata.DataInterface di,
                                      metadata.MethodSpec ms, int boffset, int length,
                                      long lvar_sig_tok, bool has_exceptions = false,
                                      List <metadata.ExceptionHeader> ehdrs  = null)
        {
            Code ret = new Code();

            ret.cil = new List <CilNode>();
            ret.ms  = ms;

            int table_id;
            int row;

            ms.m.InterpretToken((uint)lvar_sig_tok,
                                out table_id, out row);
            int idx = (int)ms.m.GetIntEntry(table_id, row, 0);

            var rtsig = ms.m.GetMethodDefSigRetTypeIndex(ms.msig);

            ret.ret_ts = ms.m.GetTypeSpec(ref rtsig, ms.gtparams, ms.gmparams);

            ret.lvar_sig_tok = idx;

            Dictionary <int, List <int> > offsets_before =
                new Dictionary <int, List <int> >(new GenericEqualityComparer <int>());

            // First, generate CilNodes for each instruction
            int offset = 0;

            while (offset < length)
            {
                CilNode n = new CilNode(ms, offset);

                /* Determine try block starts */
                if (ehdrs != null)
                {
                    foreach (var ehdr in ehdrs)
                    {
                        if (ehdr.TryILOffset == offset)
                        {
                            n.try_starts.Insert(0, ehdr);
                        }
                        if (ehdr.HandlerILOffset == offset ||
                            (ehdr.EType == metadata.ExceptionHeader.ExceptionHeaderType.Filter && ehdr.FilterOffset == offset))
                        {
                            n.handler_starts.Add(ehdr);
                        }
                        if (offset >= ehdr.HandlerILOffset &&
                            offset < ehdr.HandlerILOffset + ehdr.HandlerLength)
                        {
                            n.is_in_excpt_handler = true;
                        }
                    }
                }

                /* Parse prefixes */
                bool cont = true;
                while (cont)
                {
                    if (di.ReadByte(offset + boffset) == 0xfe)
                    {
                        switch (di.ReadByte(offset + boffset + 1))
                        {
                        case 0x16:
                            n.constrained     = true;
                            offset           += 2;
                            n.constrained_tok = di.ReadUInt(offset + boffset);
                            offset           += 4;
                            break;

                        case 0x19:
                            if ((di.ReadByte(offset + boffset + 2) & 0x01) == 0x01)
                            {
                                n.no_typecheck = true;
                            }
                            if ((di.ReadByte(offset + boffset + 2) & 0x02) == 0x02)
                            {
                                n.no_rangecheck = true;
                            }
                            if ((di.ReadByte(offset + boffset + 2) & 0x04) == 0x04)
                            {
                                n.no_nullcheck = true;
                            }
                            offset += 3;
                            break;

                        case 0x1e:
                            n.read_only = true;
                            offset     += 2;
                            break;

                        case 0x14:
                            n.tail  = true;
                            offset += 2;
                            break;

                        case 0x12:
                            n.unaligned           = true;
                            n.unaligned_alignment = di.ReadByte(offset + boffset + 2);
                            offset += 3;
                            break;

                        case 0x13:
                            n.volatile_ = true;
                            offset     += 2;
                            break;

                        default:
                            cont = false;
                            break;
                        }
                    }
                    else
                    {
                        cont = false;
                    }
                }

                /* Parse opcode */
                if (di.ReadByte(offset + boffset) == (int)Opcode.SingleOpcodes.double_)
                {
                    offset++;
                    n.opcode = OpcodeList.Opcodes[0xfe00 + di.ReadByte(offset + boffset)];
                }
                else if (di.ReadByte(offset + boffset) == (int)Opcode.SingleOpcodes.tysila)
                {
                    //if (opts.AllowTysilaOpcodes)
                    //{
                    offset++;
                    n.opcode = OpcodeList.Opcodes[0xfd00 + di.ReadByte(offset + boffset)];
                    //}
                    //else
                    //    throw new UnauthorizedAccessException("Opcodes in the range 0xfd00 - 0xfdff are not allowed in user code");
                }
                else
                {
                    n.opcode = OpcodeList.Opcodes[di.ReadByte(offset + boffset)];
                }
                offset++;

                /* Parse immediate operands */
                switch (n.opcode.inline)
                {
                case Opcode.InlineVar.InlineBrTarget:
                case Opcode.InlineVar.InlineI:
                case Opcode.InlineVar.InlineField:
                case Opcode.InlineVar.InlineMethod:
                case Opcode.InlineVar.InlineSig:
                case Opcode.InlineVar.InlineString:
                case Opcode.InlineVar.InlineTok:
                case Opcode.InlineVar.InlineType:
                case Opcode.InlineVar.ShortInlineR:
                    n.inline_int  = di.ReadInt(offset + boffset);
                    n.inline_uint = di.ReadUInt(offset + boffset);
                    n.inline_long = n.inline_int;
                    n.inline_val  = new byte[4];
                    for (int i = 0; i < 4; i++)
                    {
                        n.inline_val[i] = di.ReadByte(offset + boffset + i);
                    }
                    offset += 4;

                    if (n.opcode.inline == Opcode.InlineVar.ShortInlineR)
                    {
                        unsafe
                        {
                            fixed(int *ii = &n.inline_int)
                            {
                                fixed(float *ifl = &n.inline_float)
                                {
                                    *(int *)ifl = *ii;
                                }
                            }
                        }
                        n.inline_double = n.inline_float;
                    }
                    break;

                case Opcode.InlineVar.InlineI8:
                case Opcode.InlineVar.InlineR:
                    n.inline_int  = di.ReadInt(offset + boffset);
                    n.inline_uint = di.ReadUInt(offset + boffset);
                    n.inline_long = di.ReadLong(offset + boffset);
                    n.inline_val  = new byte[8];
                    for (int i = 0; i < 8; i++)
                    {
                        n.inline_val[i] = di.ReadByte(offset + boffset + i);
                    }
                    offset += 8;

                    if (n.opcode.inline == Opcode.InlineVar.InlineR)
                    {
                        unsafe
                        {
                            fixed(long *ii = &n.inline_long)
                            {
                                fixed(double *ifl = &n.inline_double)
                                {
                                    *(long *)ifl = *ii;
                                }
                            }
                        }
                        n.inline_float = (float)n.inline_double;
                    }

                    break;

                case Opcode.InlineVar.InlineVar:
                    //line.inline_int = LSB_Assembler.FromByteArrayI2S(code, offset);
                    //line.inline_uint = LSB_Assembler.FromByteArrayU2S(code, offset);
                    //line.inline_val = new byte[2];
                    //LSB_Assembler.SetByteArrayS(line.inline_val, 0, code, offset, 2);
                    throw new NotImplementedException();
                    offset += 2;
                    break;

                case Opcode.InlineVar.ShortInlineBrTarget:
                case Opcode.InlineVar.ShortInlineI:
                case Opcode.InlineVar.ShortInlineVar:
                    n.inline_int    = di.ReadSByte(offset + boffset);
                    n.inline_uint   = di.ReadByte(offset + boffset);
                    n.inline_long   = n.inline_int;
                    n.inline_val    = new byte[1];
                    n.inline_val[0] = di.ReadByte(offset + boffset);
                    offset         += 1;
                    break;

                case Opcode.InlineVar.InlineSwitch:
                    uint switch_len = di.ReadUInt(offset + boffset);
                    n.inline_int   = (int)switch_len;
                    n.inline_long  = n.inline_int;
                    offset        += 4;
                    n.inline_array = new List <int>();
                    for (uint switch_it = 0; switch_it < switch_len; switch_it++)
                    {
                        n.inline_array.Add(di.ReadInt(offset + boffset));
                        offset += 4;
                    }
                    break;
                }

                /* Determine the next instruction in the stream */
                switch (n.opcode.ctrl)
                {
                case Opcode.ControlFlow.BRANCH:
                    n.il_offsets_after.Add(offset + n.inline_int);
                    break;

                case Opcode.ControlFlow.COND_BRANCH:
                    if (n.opcode.opcode1 == Opcode.SingleOpcodes.switch_)
                    {
                        foreach (int jmp_target in n.inline_array)
                        {
                            n.il_offsets_after.Add(offset + jmp_target);
                        }
                        n.il_offsets_after.Add(offset);
                    }
                    else
                    {
                        n.il_offsets_after.Add(offset);
                        n.il_offsets_after.Add(offset + n.inline_int);
                    }
                    break;

                case Opcode.ControlFlow.NEXT:
                case Opcode.ControlFlow.CALL:
                case Opcode.ControlFlow.BREAK:
                    n.il_offsets_after.Add(offset);
                    break;
                }

                n.il_offset_after           = offset;
                ret.offset_map[n.il_offset] = n;
                ret.offset_order.Add(n.il_offset);

                // Store this node as the offset_before whatever it
                //  references
                foreach (var offset_after in n.il_offsets_after)
                {
                    List <int> after_list;
                    if (!offsets_before.TryGetValue(offset_after,
                                                    out after_list))
                    {
                        after_list = new List <int>();
                        offsets_before[offset_after] = after_list;
                    }
                    if (!after_list.Contains(n.il_offset))
                    {
                        after_list.Add(n.il_offset);
                    }
                }

                ret.cil.Add(n);
            }

            /* Now determine which instructions are branch targets
             * so we don't coalesce a block containing
             * a branch into a single instruction */
            foreach (var n in ret.cil)
            {
                if (n.opcode.ctrl == Opcode.ControlFlow.BRANCH)
                {
                    ret.offset_map[n.il_offsets_after[0]].is_block_start = true;
                }
                else if (n.opcode.ctrl == Opcode.ControlFlow.COND_BRANCH)
                {
                    ret.offset_map[n.il_offsets_after[1]].is_block_start = true;
                }
            }

            ret.starts = new List <CilNode>();

            if (ret.cil.Count > 0)
            {
                ret.starts.Add(ret.cil[0]);
            }

            if (ehdrs != null)
            {
                foreach (var e in ehdrs)
                {
                    ret.starts.Add(ret.offset_map[e.HandlerILOffset]);

                    if (e.EType == metadata.ExceptionHeader.ExceptionHeaderType.Filter)
                    {
                        var filter_start = ret.offset_map[e.FilterOffset];
                        ret.starts.Add(filter_start);
                        filter_start.is_filter_start = true;
                    }
                }
            }

            ret.ehdrs = ehdrs;

            foreach (var n in ret.cil)
            {
                foreach (var next in n.il_offsets_after)
                {
                    var next_n = ret.offset_map[next];
                    next_n.prev.Add(n);
                }
            }

            return(ret);
        }
Exemple #8
0
 protected internal abstract bool NeedsBoxRetType(metadata.MethodSpec ms);
Exemple #9
0
 protected internal abstract Code AssembleBoxRetTypeMethod(metadata.MethodSpec ms, TysilaState s);
Exemple #10
0
 public static extern void *JitCompile(metadata.MethodSpec ms);
Exemple #11
0
 public CilNode(metadata.MethodSpec ms, int cil_offset)
 {
     m         = ms.m;
     il_offset = cil_offset;
     _ms       = ms;
 }
Exemple #12
0
        static void Main(string[] args)
        {
            var    argc = args.Length;
            char   c;
            var    go          = new XGetoptCS.XGetopt();
            var    arg_str     = "t:L:f:e:o:d:qDC:H:m:i";
            string target      = "x86";
            string debug_file  = null;
            string output_file = null;
            string epoint      = null;
            string cfile       = null;
            string hfile       = null;
            bool   quiet       = false;
            bool   require_metadata_version_match = true;
            bool   interactive = false;
            string act_epoint  = null;
            Dictionary <string, object> opts = new Dictionary <string, object>();

            while ((c = go.Getopt(argc, args, arg_str)) != '\0')
            {
                switch (c)
                {
                case 't':
                    target = go.Optarg;
                    break;

                case 'L':
                    new_search_dirs.Add(go.Optarg);
                    break;

                case 'd':
                    debug_file = go.Optarg;
                    break;

                case 'o':
                    output_file = go.Optarg;
                    break;

                case 'e':
                    epoint = go.Optarg;
                    break;

                case 'q':
                    quiet = true;
                    break;

                case 'D':
                    require_metadata_version_match = false;
                    break;

                case 'C':
                    cfile = go.Optarg;
                    break;

                case 'H':
                    hfile = go.Optarg;
                    break;

                case 'f':
                    parse_f_option(go);
                    break;

                case 'i':
                    interactive = true;
                    break;

                case 'g':
                    do_dwarf = true;
                    break;

                case 'm':
                {
                    var    opt    = go.Optarg;
                    object optval = true;
                    if (opt.Contains("="))
                    {
                        var optvals = opt.Substring(opt.IndexOf("=") + 1);
                        opt = opt.Substring(0, opt.IndexOf("="));

                        int intval;
                        if (optvals.ToLower() == "false" || optvals.ToLower() == "off" || optvals.ToLower() == "no")
                        {
                            optval = false;
                        }
                        else if (optvals.ToLower() == "true" || optvals.ToLower() == "on" || optvals.ToLower() == "yes")
                        {
                            optval = true;
                        }
                        else if (int.TryParse(optvals, out intval))
                        {
                            optval = intval;
                        }
                        else
                        {
                            optval = optvals;
                        }
                    }
                    else if (opt.StartsWith("no-"))
                    {
                        opt    = opt.Substring(3);
                        optval = false;
                    }
                    opts[opt] = optval;
                }
                break;
                }
            }

            var fname = go.Optarg;

            if (fname == String.Empty)
            {
                Console.WriteLine("No input file specified");
                return;
            }

            // Insert library directories specified on the command line before the defaults
            search_dirs.InsertRange(0, new_search_dirs);

            if (cfile != null && hfile == null)
            {
                Console.WriteLine("-H must be used if -C is used");
                return;
            }

            libtysila5.libtysila.AssemblyLoader al = new libtysila5.libtysila.AssemblyLoader(
                new FileSystemFileLoader());

            /* Load up type forwarders */
            foreach (var libdir in search_dirs)
            {
                try
                {
                    var di = new DirectoryInfo(libdir);
                    if (di.Exists)
                    {
                        foreach (var tfw_file in di.GetFiles("*.tfw"))
                        {
                            var tfr = new StreamReader(tfw_file.OpenRead());
                            while (!tfr.EndOfStream)
                            {
                                var tfr_line   = tfr.ReadLine();
                                var tfr_lsplit = tfr_line.Split('=');
                                al.TypeForwarders[tfr_lsplit[0]] = tfr_lsplit[1];
                            }
                            tfr.Close();
                        }
                    }
                }
                catch (Exception) { }
            }

            //search_dirs.Add(@"..\mono\corlib");
            al.RequireVersionMatch = require_metadata_version_match;

            // add containing directory of input to search dirs
            var ifi = new FileInfo(fname);

            search_dirs.Add(ifi.DirectoryName);

            var m = al.GetAssembly(fname);

            if (m == null)
            {
                Console.WriteLine("Input file " + fname + " not found");
                throw new Exception(fname + " not found");
            }

            t = libtysila5.target.Target.targets[target];
            // try and set target options
            foreach (var kvp in opts)
            {
                if (!t.Options.TrySet(kvp.Key, kvp.Value))
                {
                    Console.WriteLine("Unable to set target option " + kvp.Key + " to " + kvp.Value.ToString());
                    return;
                }
            }

            if (interactive)
            {
                if (new Interactive(m, t).DoInteractive() == false)
                {
                    return;
                }
            }

            libtysila5.dwarf.DwarfCU dwarf = null;
            if (do_dwarf)
            {
                dwarf = new libtysila5.dwarf.DwarfCU(t, m);
            }

            libtysila5.TysilaState s = new libtysila5.TysilaState();

            if (output_file != null)
            {
                var bf = new binary_library.elf.ElfFile(binary_library.Bitness.Bits32);
                s.bf = bf;
                bf.Init();
                bf.Architecture = target;
                var st = new libtysila5.StringTable(
                    m.GetStringEntry(metadata.MetadataStream.tid_Module,
                                     1, 1), al, t);
                s.st = st;
                s.r  = new libtysila5.CachingRequestor(m);
                t.InitIntcalls();

                /* for now, just assemble all public and protected
                 * non-generic methods in public types, plus the
                 * entry point */
                StringBuilder debug = new StringBuilder();
                for (int i = 1; i <= m.table_rows[metadata.MetadataStream.tid_MethodDef]; i++)
                {
                    metadata.MethodSpec ms = new metadata.MethodSpec
                    {
                        m     = m,
                        mdrow = i,
                        msig  = 0
                    };

                    ms.type = new metadata.TypeSpec
                    {
                        m     = m,
                        tdrow = m.methoddef_owners[ms.mdrow]
                    };

                    var mflags = m.GetIntEntry(metadata.MetadataStream.tid_MethodDef,
                                               i, 2);
                    var tflags = m.GetIntEntry(metadata.MetadataStream.tid_TypeDef,
                                               ms.type.tdrow, 0);

                    mflags &= 0x7;
                    tflags &= 0x7;

                    ms.msig = (int)m.GetIntEntry(metadata.MetadataStream.tid_MethodDef,
                                                 i, 4);

                    /* See if this is the entry point */
                    int tid, row;
                    m.InterpretToken(m.entry_point_token, out tid, out row);
                    if (tid == metadata.MetadataStream.tid_MethodDef)
                    {
                        if (row == i)
                        {
                            if (epoint != null)
                            {
                                ms.aliases = new List <string> {
                                    epoint
                                }
                            }
                            ;

                            mflags = 6;
                            tflags = 1;

                            ms.AlwaysCompile = true;
                            act_epoint       = ms.MangleMethod();
                        }
                    }

                    /* See if we have an always compile attribute */
                    if (ms.HasCustomAttribute("_ZN14libsupcs#2Edll8libsupcs22AlwaysCompileAttribute_7#2Ector_Rv_P1u1t") ||
                        ms.type.HasCustomAttribute("_ZN14libsupcs#2Edll8libsupcs22AlwaysCompileAttribute_7#2Ector_Rv_P1u1t"))
                    {
                        mflags = 6;
                        tflags = 1;

                        ms.AlwaysCompile = true;
                    }

                    if (ms.type.IsGenericTemplate == false &&
                        ms.IsGenericTemplate == false &&
                        (mflags == 0x4 || mflags == 0x5 || mflags == 0x6) &&
                        tflags != 0)
                    {
                        s.r.MethodRequestor.Request(ms);
                    }
                }

                /* Also assemble all public non-generic type infos */
                for (int i = 1; i <= m.table_rows[metadata.MetadataStream.tid_TypeDef]; i++)
                {
                    var flags = (int)m.GetIntEntry(metadata.MetadataStream.tid_TypeDef,
                                                   i, 0);
                    if (((flags & 0x7) != 0x1) &&
                        ((flags & 0x7) != 0x2))
                    {
                        continue;
                    }
                    var ts = new metadata.TypeSpec {
                        m = m, tdrow = i
                    };
                    if (ts.IsGeneric)
                    {
                        continue;
                    }
                    s.r.StaticFieldRequestor.Request(ts);
                    s.r.VTableRequestor.Request(ts.Box);
                }

                /* If corlib, add in the default equality comparers so we don't have to jit these
                 * commonly used classes */
                if (m.is_corlib)
                {
                    s.r.MethodRequestor.Request(m.GetMethodSpec(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemByte }), ".ctor"));
                    s.r.MethodRequestor.Request(m.GetMethodSpec(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemInt8 }), ".ctor"));
                    s.r.MethodRequestor.Request(m.GetMethodSpec(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemInt16 }), ".ctor"));
                    s.r.MethodRequestor.Request(m.GetMethodSpec(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemUInt16 }), ".ctor"));
                    s.r.MethodRequestor.Request(m.GetMethodSpec(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemInt32 }), ".ctor"));
                    s.r.MethodRequestor.Request(m.GetMethodSpec(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemUInt32 }), ".ctor"));
                    s.r.MethodRequestor.Request(m.GetMethodSpec(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemInt64 }), ".ctor"));
                    s.r.MethodRequestor.Request(m.GetMethodSpec(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemUInt64 }), ".ctor"));
                    s.r.MethodRequestor.Request(m.GetMethodSpec(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemString }), ".ctor"));
                    s.r.MethodRequestor.Request(m.GetMethodSpec(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemObject }), ".ctor"));

                    s.r.VTableRequestor.Request(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemByte }));
                    s.r.VTableRequestor.Request(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemInt8 }));
                    s.r.VTableRequestor.Request(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemInt16 }));
                    s.r.VTableRequestor.Request(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemUInt16 }));
                    s.r.VTableRequestor.Request(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemInt32 }));
                    s.r.VTableRequestor.Request(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemUInt32 }));
                    s.r.VTableRequestor.Request(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemInt64 }));
                    s.r.VTableRequestor.Request(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemUInt64 }));
                    s.r.VTableRequestor.Request(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemString }));
                    s.r.VTableRequestor.Request(m.GetTypeSpec("System.Collections.Generic", "GenericEqualityComparer`1", new metadata.TypeSpec[] { m.SystemObject }));
                }

                /* Generate a thread-local data section.  We may not use it. */
                var tlsos = bf.CreateContentsSection();
                tlsos.Name          = ".tdata";
                tlsos.IsAlloc       = true;
                tlsos.IsExecutable  = false;
                tlsos.IsWriteable   = true;
                tlsos.IsThreadLocal = true;

                while (!s.r.Empty)
                {
                    if (!s.r.MethodRequestor.Empty)
                    {
                        var ms = s.r.MethodRequestor.GetNext();

                        ISection tsect    = null;
                        ISection datasect = null;
                        if (func_sects && !ms.ms.AlwaysCompile)
                        {
                            tsect    = get_decorated_section(bf, bf.GetTextSection(), "." + ms.ms.MangleMethod());
                            datasect = get_decorated_section(bf, bf.GetDataSection(), "." + ms.ms.MangleMethod() + "_SignatureTable");
                        }
                        else if (class_sects && !ms.ms.AlwaysCompile)
                        {
                            tsect    = get_decorated_section(bf, bf.GetTextSection(), "." + ms.ms.type.MangleType());
                            datasect = get_decorated_section(bf, bf.GetDataSection(), "." + ms.ms.type.MangleType() + "_SignatureTable");
                        }

                        libtysila5.libtysila.AssembleMethod(ms.ms,
                                                            bf, t, s, debug, m, ms.c, tsect, datasect, dwarf);
                        if (!quiet)
                        {
                            Console.WriteLine(ms.ms.m.MangleMethod(ms.ms));
                        }
                    }
                    else if (!s.r.StaticFieldRequestor.Empty)
                    {
                        var sf = s.r.StaticFieldRequestor.GetNext();

                        ISection tsect = null;
                        if (data_sects && !sf.AlwaysCompile)
                        {
                            tsect = get_decorated_section(bf, bf.GetDataSection(), "." + sf.MangleType() + "S");
                        }
                        else if (class_sects && !sf.AlwaysCompile)
                        {
                            tsect = get_decorated_section(bf, bf.GetDataSection(), "." + sf.MangleType() + "S");
                        }

                        libtysila5.layout.Layout.OutputStaticFields(sf,
                                                                    t, bf, m, tsect, tlsos);
                        if (!quiet)
                        {
                            Console.WriteLine(sf.MangleType() + "S");
                        }
                    }
                    else if (!s.r.EHRequestor.Empty)
                    {
                        var eh = s.r.EHRequestor.GetNext();

                        ISection tsect = null;
                        if (func_sects && !eh.ms.AlwaysCompile)
                        {
                            tsect = get_decorated_section(bf, bf.GetRDataSection(), "." + eh.ms.MangleMethod() + "EH");
                        }
                        else if (class_sects && !eh.ms.AlwaysCompile)
                        {
                            tsect = get_decorated_section(bf, bf.GetRDataSection(), "." + eh.ms.type.MangleType() + "EH");
                        }

                        libtysila5.layout.Layout.OutputEHdr(eh,
                                                            t, bf, s, m, tsect);
                        if (!quiet)
                        {
                            Console.WriteLine(eh.ms.MangleMethod() + "EH");
                        }
                    }
                    else if (!s.r.VTableRequestor.Empty)
                    {
                        var vt = s.r.VTableRequestor.GetNext();

                        ISection tsect     = null;
                        ISection data_sect = null;
                        if (data_sects && !vt.AlwaysCompile)
                        {
                            tsect     = get_decorated_section(bf, bf.GetRDataSection(), "." + vt.MangleType());
                            data_sect = get_decorated_section(bf, bf.GetDataSection(), "." + vt.MangleType() + "_SignatureTable");
                        }
                        else if (class_sects && !vt.AlwaysCompile)
                        {
                            tsect     = get_decorated_section(bf, bf.GetTextSection(), "." + vt.MangleType());
                            data_sect = get_decorated_section(bf, bf.GetDataSection(), "." + vt.MangleType() + "_SignatureTable");
                        }

                        libtysila5.layout.Layout.OutputVTable(vt,
                                                              t, bf, s, m, tsect, data_sect);
                        if (!quiet)
                        {
                            Console.WriteLine(vt.MangleType());
                        }
                    }
                    else if (!s.r.DelegateRequestor.Empty)
                    {
                        var d = s.r.DelegateRequestor.GetNext();
                        libtysila5.ir.ConvertToIR.CreateDelegate(d, t, s);
                        if (!quiet)
                        {
                            Console.WriteLine(d.MangleType() + "D");
                        }
                    }
                    else if (!s.r.BoxedMethodRequestor.Empty)
                    {
                        var bm = s.r.BoxedMethodRequestor.GetNext();

                        ISection tsect = null;
                        if (func_sects && !bm.ms.AlwaysCompile)
                        {
                            tsect = get_decorated_section(bf, bf.GetTextSection(), "." + bm.ms.MangleMethod());
                        }
                        else if (class_sects && !bm.ms.AlwaysCompile)
                        {
                            tsect = get_decorated_section(bf, bf.GetTextSection(), "." + bm.ms.type.MangleType());
                        }

                        libtysila5.libtysila.AssembleBoxedMethod(bm.ms,
                                                                 bf, t, s, debug, tsect);
                        if (!quiet)
                        {
                            Console.WriteLine(bm.ms.MangleMethod());
                        }
                    }
                }

                if (debug_file != null)
                {
                    string d = debug.ToString();

                    StreamWriter sw = new StreamWriter(debug_file);
                    sw.Write(d);
                    sw.Close();
                }

                if (tlsos.Length > 0)
                {
                    bf.AddSection(tlsos);
                }

                /* String table */
                st.WriteToOutput(bf, m, t);

                /* Include original metadata */
                var rdata = bf.GetRDataSection();
                rdata.Align(t.GetPointerSize());
                var mdsym = bf.CreateSymbol();
                mdsym.Name       = m.AssemblyName;
                mdsym.ObjectType = binary_library.SymbolObjectType.Object;
                mdsym.Offset     = (ulong)rdata.Data.Count;
                mdsym.Type       = binary_library.SymbolType.Global;
                var len = m.file.GetLength();
                mdsym.Size = len;
                rdata.AddSymbol(mdsym);

                for (int i = 0; i < len; i++)
                {
                    rdata.Data.Add(m.file.ReadByte(i));
                }

                var mdsymend = bf.CreateSymbol();
                mdsymend.Name       = m.AssemblyName + "_end";
                mdsymend.ObjectType = binary_library.SymbolObjectType.Object;
                mdsymend.Offset     = (ulong)rdata.Data.Count;
                mdsymend.Type       = binary_library.SymbolType.Global;
                mdsymend.Size       = 0;
                rdata.AddSymbol(mdsymend);

                /* Add resource symbol if present */
                if (m.GetPEFile().ResourcesSize != 0)
                {
                    var rsym = bf.CreateSymbol();
                    rsym.Name       = m.AssemblyName + "_resources";
                    rsym.ObjectType = SymbolObjectType.Object;
                    rsym.Offset     = (ulong)m.GetPEFile().ResourcesOffset + mdsym.Offset;
                    rsym.Type       = SymbolType.Global;
                    rsym.Size       = m.GetPEFile().ResourcesSize;
                    rdata.AddSymbol(rsym);
                }

                /* Add comment */
                var csect = bf.CreateContentsSection();
                csect.IsAlloc      = false;
                csect.IsExecutable = false;
                csect.IsWriteable  = false;
                csect.Name         = ".comment";
                var cbytes = Encoding.ASCII.GetBytes(comment);
                foreach (var cbyte in cbytes)
                {
                    csect.Data.Add(cbyte);
                }
                csect.Data.Add(0);
                if (act_epoint != null)
                {
                    var epbytes = Encoding.ASCII.GetBytes("entry: " +
                                                          act_epoint);
                    foreach (var epbyte in epbytes)
                    {
                        csect.Data.Add(epbyte);
                    }
                    csect.Data.Add(0);
                }
                bf.AddSection(csect);

                /* Add debugger sections */
                if (dwarf != null)
                {
                    var dwarf_sects = new libtysila5.dwarf.DwarfSections(bf);
                    dwarf.WriteToOutput(dwarf_sects);
                }


                /* Write output file */
                bf.Filename = output_file;
                bf.Write();
            }

            if (hfile != null)
            {
                COutput.WriteHeader(m, t, hfile, cfile);
            }
        }
Exemple #13
0
 public abstract bool AssembleJitStub(metadata.MethodSpec ms, libtysila5.target.Target t,
                                      binary_library.IBinaryFile bf, libtysila5.TysilaState s);