Exemplo n.º 1
0
 public LayoutManager(libtysila.Assembler ass, SymbolTable stab)
 {
     LoadLayout(ass.GetTysosTypeLayout(), stab);
     LoadLayout(ass.GetTysosMethodLayout(), stab);
     LoadLayout(ass.GetTysosGenericTypeLayout(), stab);
     LoadLayout(ass.GetTysosGenericTypeDefinitionLayout(), stab);
     LoadLayout(ass.GetTysosFieldLayout(), stab);
     LoadLayout(ass.GetTysosAssemblyLayout(), stab);
 }
Exemplo n.º 2
0
        static void Main(string[] args)
        {
            file_loader      = new JitFileLoader();
            member_requestor = new JitMemberRequestor();
            output           = new JitOutput();
            mmgr             = new JitMemoryManager();

            file_loader.LoadModuleToMemory("test_002", System.IO.Path.Combine(Environment.CurrentDirectory, "../../../testsuite/test_002/bin/Debug/test_002.exe"));
            file_loader.LoadModuleToMemory("mscorlib", System.IO.Path.Combine(Environment.CurrentDirectory, "../../../mono/corlib/mscorlib.dll"));
            file_loader.LoadModuleToMemory("libsupcs", System.IO.Path.Combine(Environment.CurrentDirectory, "../../../libsupcs/bin/Release/libsupcs.dll"));

            ass = libtysila.Assembler.CreateAssembler(libtysila.Assembler.ParseArchitectureString(arch), file_loader, member_requestor, null);
            member_requestor.Assembler = ass;
            libtysila.Metadata module = ass.FindAssembly("test_002");
            libtysila.Assembler.MethodToCompile?mtc = module.GetEntryPoint(ass);
            member_requestor.RequestMethod(mtc.Value, false);

            // the jit stub to call
            symbols.Add("__jit", 0);

            // Now do the compilation
            int objects_assembled;

            do
            {
                objects_assembled = 0;

                JitMemberRequestor.JitMethod next_meth = member_requestor.GetNextJitMethod();
                if (next_meth != null)
                {
                    if (debug)
                    {
                        Console.WriteLine("Method: " + next_meth.mtc.ToString() + ((next_meth.is_jit_stub) ? " (JIT stub)" : ""));
                    }
                    if (next_meth.is_jit_stub == false)
                    {
                        ass.AssembleMethod(next_meth.mtc, output, null);
                    }
                    else
                    {
                        // TODO: add jit stub
                        output.AddTextSymbol(output.GetText().Count, libtysila.Mangler2.MangleMethod(next_meth.mtc, ass), false, true, false);

                        /* for now
                         *
                         * mov rax, __jit
                         * jmp rax
                         */
                        byte[] jit_stub = new byte[] { 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0 };
                        output.AddTextRelocation(output.GetText().Count + 2, "__jit", libtysila.x86_64.x86_64_elf64.R_X86_64_64, 0);
                        output.text.AddRange(jit_stub);
                    }
                    objects_assembled++;
                }

                libtysila.Assembler.MethodToCompile?next_mi = member_requestor.GetNextJitMethodInfo();
                if (next_mi.HasValue)
                {
                    if (debug)
                    {
                        Console.WriteLine("MethodInfo: " + next_mi.Value.ToString());
                    }
                    //ass.AssembleMethodInfo(next_mi.Value, output);

                    if (next_mi.Value.MetadataToken.HasValue)
                    {
                        // Write a short method info - magic (0x01010101), uint token, uintptr metadata_ptr

                        // TODO: modify for 32 bits
                        byte[] smi   = new byte[16];
                        uint   magic = 0x01010101;
                        BitConverter.GetBytes(magic).CopyTo(smi, 0);
                        BitConverter.GetBytes(next_mi.Value.MetadataToken.Value).CopyTo(smi, 4);
                        BitConverter.GetBytes((ulong)symbols["metadata_" + next_mi.Value.meth.m.ModuleName]).CopyTo(smi, 8);

                        output.AddRodataSymbol(output.GetRodata().Count, libtysila.Mangler2.MangleMethodInfoSymbol(next_mi.Value, ass));
                        output.rodata.AddRange(smi);
                    }
                    else
                    {
                        throw new Exception("No metadata token specified in requested method");
                    }

                    objects_assembled++;
                }

                libtysila.Assembler.TypeToCompile?next_ti = member_requestor.GetNextJITType();
                if (next_ti.HasValue)
                {
                    if (debug)
                    {
                        Console.WriteLine("TypeInfo: " + next_ti.Value.ToString());
                    }
                    //ass.AssembleType(next_ti.Value, output);
                    objects_assembled++;
                }

                libtysila.Metadata next_mod = member_requestor.GetNextModule();
                if (next_mod != null)
                {
                    if (debug)
                    {
                        Console.WriteLine("Module: " + next_mod.ModuleName);
                    }
                    ass.AssembleModuleInfo(next_mod, output);
                    objects_assembled++;
                }

                libtysila.Metadata next_ass = member_requestor.GetNextAssembly();
                if (next_mod != null)
                {
                    if (debug)
                    {
                        Console.WriteLine("Assembly: " + next_ass.ModuleName);
                    }
                    ass.AssembleAssemblyInfo(next_ass, output);
                    objects_assembled++;
                }
            } while (objects_assembled > 0);

            // Write to the output
            int len       = output.text.Count + output.data.Count + output.rodata.Count;
            int base_addr = mmgr.Alloc(len);

            // Store symbols
            foreach (KeyValuePair <string, int> kvp in output.text_sym)
            {
                RegisterSymbol(kvp.Key, kvp.Value + base_addr);
            }
            foreach (KeyValuePair <string, int> kvp in output.data_sym)
            {
                RegisterSymbol(kvp.Key, kvp.Value + base_addr);
            }
            foreach (KeyValuePair <string, int> kvp in output.rodata_sym)
            {
                RegisterSymbol(kvp.Key, kvp.Value + base_addr);
            }

            // Write the data
            int offset = base_addr;

            output.text.CopyTo(mmgr.Memory, offset);
            offset += output.text.Count;
            output.data.CopyTo(mmgr.Memory, offset);
            offset += output.data.Count;
            output.rodata.CopyTo(mmgr.Memory, offset);

            // Perform relocations
            foreach (KeyValuePair <int, JitOutput.Relocation> kvp in output.text_rel)
            {
                DoRelocation(kvp.Key + base_addr, kvp.Value);
            }
            foreach (KeyValuePair <int, JitOutput.Relocation> kvp in output.data_rel)
            {
                DoRelocation(kvp.Key + base_addr, kvp.Value);
            }
            foreach (KeyValuePair <int, JitOutput.Relocation> kvp in output.rodata_rel)
            {
                DoRelocation(kvp.Key + base_addr, kvp.Value);
            }
        }