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); }
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 }
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"); }
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); }
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); }
public TysosMethod(metadata.MethodSpec ms, TysosType owning_type) { mspec = ms; OwningType = owning_type; }
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); }
protected internal abstract bool NeedsBoxRetType(metadata.MethodSpec ms);
protected internal abstract Code AssembleBoxRetTypeMethod(metadata.MethodSpec ms, TysilaState s);
public static extern void *JitCompile(metadata.MethodSpec ms);
public CilNode(metadata.MethodSpec ms, int cil_offset) { m = ms.m; il_offset = cil_offset; _ms = ms; }
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); } }
public abstract bool AssembleJitStub(metadata.MethodSpec ms, libtysila5.target.Target t, binary_library.IBinaryFile bf, libtysila5.TysilaState s);