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); }
static int Main(string[] args) { /* Parse args */ var argc = args.Length; char c; var go = new XGetoptCS.XGetopt(); var arg_str = "t:L:o:"; while ((c = go.Getopt(argc, args, arg_str)) != '\0') { switch (c) { case 't': arch = go.Optarg; break; case 'L': new_search_dirs.Add(go.Optarg); break; case 'o': output_name = go.Optarg; break; case '?': dump_opts(); return(-1); } } tysila4.Program.search_dirs.InsertRange(0, new_search_dirs); var curopt = go.Optind; while (curopt < argc) { input_files.Add(args[curopt++]); } if (input_files.Count == 0) { System.Console.WriteLine("No input files specified"); dump_opts(); return(-1); } /* Load up each input file in turn */ var ifiles = new List <binary_library.IBinaryFile>(); foreach (var ifname in input_files) { var ifinfo = new System.IO.FileInfo(ifname); if (!ifinfo.Exists) { throw new System.IO.FileNotFoundException("Cannot find: " + ifname); } /* Determine file type from extension */ binary_library.IBinaryFile ifobj = null; if (ifinfo.Extension == ".o" || ifinfo.Extension == ".obj") { ifobj = new binary_library.elf.ElfFile(); } if (ifobj == null) { ifobj = binary_library.BinaryFile.CreateBinaryFile(ifinfo.Extension); } if (ifobj == null) { throw new Exception("Unsupported file type: " + ifinfo.FullName); } /* Load up the particular file */ ifobj.Filename = ifinfo.FullName; ifobj.Read(); ifiles.Add(ifobj); } /* Get a list of all defined symbols */ var def_syms = new Dictionary <string, binary_library.ISymbol>(); foreach (var file in ifiles) { var sym_count = file.GetSymbolCount(); for (int i = 0; i < sym_count; i++) { var sym = file.GetSymbol(i); if (sym.DefinedIn != null && sym.Type != binary_library.SymbolType.Undefined) { def_syms[sym.Name] = sym; } } } /* Get a list of those relocations which are missing */ var missing = new Dictionary <string, binary_library.ISymbol>(); foreach (var file in ifiles) { var reloc_count = file.GetRelocationCount(); for (int i = 0; i < reloc_count; i++) { var reloc = file.GetRelocation(i); if (reloc.References != null && !def_syms.ContainsKey(reloc.References.Name)) { if (reloc.References.Name == "_Zu1O_7#2Ector_Rv_P1u1t") { System.Diagnostics.Debugger.Break(); } missing[reloc.References.Name] = reloc.References; } } } /* Generate an output object */ var o = new binary_library.elf.ElfFile(ifiles[0].Bitness); o.Init(); o.Architecture = arch; o.Filename = output_name; /* Generate dummy module */ var ofi = new System.IO.FileInfo(output_name); var ms = new metadata.MetadataStream(ofi.Name.Substring(0, ofi.Name.Length - ofi.Extension.Length)); ms.al = new libtysila5.libtysila.AssemblyLoader(new tysila4.FileSystemFileLoader()); ms.LoadBuiltinTypes(); /* Load up assembler target */ var t = libtysila5.target.Target.targets[arch]; var fsi = new System.IO.FileInfo(output_name); var s = new libtysila5.TysilaState(); s.st = new libtysila5.StringTable(fsi.Name.Substring(0, fsi.Name.Length - fsi.Extension.Length), ms.al, t); /* Generate signature of missing_function(string) to call */ var special_c = new libtysila5.Code { ms = new metadata.MethodSpec { m = ms } }; var special = special_c.special_meths; var missing_msig = special.CreateMethodSignature(null, new metadata.TypeSpec[] { ms.SystemString }); /* Generate stub functions for missing methods */ var m = missing.Keys; var missing_types = new List <string>(); var other_missing = new List <string>(); foreach (var str in m) { try { if (ms.IsMangledMethod(str)) { GenerateMissingMethod(str, ms, t, missing_msig, o, s); } else { ms.IsMangledMethod(str); missing_types.Add(str); } } catch (ArgumentException) { other_missing.Add(str); } } /* Write out */ s.st.WriteToOutput(o, ms, t); o.Write(); /* Dump missing types */ if (missing_types.Count > 0) { Console.WriteLine("Warning: the following missing types were also found:"); foreach (var mt in missing_types) { Console.WriteLine(" " + mt); } } return(0); }