示例#1
0
 public void Write(binary_library.ISection str)
 {
     foreach (var c in d)
     {
         str.Data.Add(c);
     }
 }
示例#2
0
        public void WriteToOutput(binary_library.IBinaryFile of,
                                  metadata.MetadataStream ms, target.Target t,
                                  binary_library.ISection rd = null)
        {
            if (str_tab.Count == 0)
            {
                return;
            }

            if (rd == null)
            {
                rd = of.GetRDataSection();
            }
            rd.Align(t.GetCTSize(ir.Opcode.ct_object));

            var stab_lab = of.CreateSymbol();

            stab_lab.Name       = Label;
            stab_lab.ObjectType = binary_library.SymbolObjectType.Object;
            stab_lab.Offset     = (ulong)rd.Data.Count;
            stab_lab.Type       = binary_library.SymbolType.Weak;
            rd.AddSymbol(stab_lab);

            int stab_base = rd.Data.Count;

            foreach (byte b in str_tab)
            {
                rd.Data.Add(b);
            }

            foreach (var kvp in sig_metadata_addrs)
            {
                var reloc = of.CreateRelocation();
                reloc.DefinedIn = rd;
                reloc.Type      = t.GetDataToDataReloc();
                reloc.Addend    = 0;

                if (sig_metadata_addends.ContainsKey(kvp.Key))
                {
                    reloc.Addend = sig_metadata_addends[kvp.Key];
                }

                var md_lab = of.CreateSymbol();
                md_lab.Name       = kvp.Value;
                md_lab.ObjectType = binary_library.SymbolObjectType.Object;

                reloc.References = md_lab;
                reloc.Offset     = (ulong)(kvp.Key + stab_base);
                of.AddRelocation(reloc);
            }

            stab_lab.Size = rd.Data.Count - (int)stab_lab.Offset;
        }
示例#3
0
        public DwarfSections(binary_library.IBinaryFile _bf)
        {
            bf = _bf;

            abbrev = CreateDwarfSection("abbrev");
            //aranges = CreateDwarfSection("aranges");
            frame = CreateDwarfSection("frame");
            info  = CreateDwarfSection("info");
            line  = CreateDwarfSection("line");
            //loc = CreateDwarfSection("loc");
            //macinfo = CreateDwarfSection("macinfo");
            pubnames = CreateDwarfSection("pubnames");
            pubtypes = CreateDwarfSection("pubtypes");
            //ranges = CreateDwarfSection("ranges");
            str = CreateDwarfSection("str");
            //types = CreateDwarfSection("types");
        }
示例#4
0
        public static bool AssembleBoxedMethod(metadata.MethodSpec ms,
                                               binary_library.IBinaryFile bf, target.Target t,
                                               TysilaState s,
                                               StringBuilder debug_passes = null,
                                               binary_library.ISection ts = null)
        {
            if (ts == null)
            {
                ts = bf.GetTextSection();
            }
            s.bf           = bf;
            s.text_section = ts;

            // Symbol
            List <binary_library.ISymbol> meth_syms = new List <binary_library.ISymbol>();
            var mangled_name = ms.MangleMethod();
            var meth_sym     = bf.CreateSymbol();

            meth_sym.Name       = mangled_name;
            meth_sym.ObjectType = binary_library.SymbolObjectType.Function;
            meth_sym.Offset     = (ulong)ts.Data.Count;
            meth_sym.Type       = binary_library.SymbolType.Weak;
            ts.AddSymbol(meth_sym);
            meth_syms.Add(meth_sym);

            Code c = ms.ret_type_needs_boxing ? t.AssembleBoxRetTypeMethod(ms, s) : t.AssembleBoxedMethod(ms, s);

            c.t = t;
            t.AssemblePass(c);

            foreach (var sym in meth_syms)
            {
                sym.Size = ts.Data.Count - (int)sym.Offset;
            }

            DumpDebug(debug_passes, meth_syms, c);

            return(true);
        }
示例#5
0
        public static bool AssembleMethod(metadata.MethodSpec ms,
                                          binary_library.IBinaryFile bf, target.Target t,
                                          TysilaState s,
                                          StringBuilder debug_passes        = null,
                                          MetadataStream base_m             = null,
                                          Code code_override                = null,
                                          binary_library.ISection ts        = null,
                                          binary_library.ISection data_sect = null,
                                          dwarf.DwarfCU dcu = null)
        {
            if (ms.ret_type_needs_boxing)
            {
                throw new Exception("AssembleMethod called for box rettype stub - use AssembleBoxedMethod instead");
            }
            if (ms.is_boxed)
            {
                throw new Exception("AssembleMethod called for boxed method - use AssembleBoxedMethod instead");
            }

            if (ts == null)
            {
                ts = bf.GetTextSection();
            }
            s.bf           = bf;
            s.text_section = ts;
            binary_library.SymbolType sym_st = binary_library.SymbolType.Global;

            var csite = ms.msig;
            var mdef  = ms.mdrow;
            var m     = ms.m;

            /* Don't compile if not for this architecture */
            if (!t.IsMethodValid(ms))
            {
                return(false);
            }

            // Get method RVA, don't compile if no body
            var rva = m.GetIntEntry(metadata.MetadataStream.tid_MethodDef,
                                    mdef, 0);

            // New signature table
            s.sigt = new SignatureTable(ms.MangleMethod());

            /* Is this an array method? */
            if (rva == 0 &&
                ms.type != null &&
                ms.type.stype == TypeSpec.SpecialType.Array &&
                code_override == null)
            {
                if (ms.name_override == "Get")
                {
                    code_override = ir.ConvertToIR.CreateArrayGet(ms, t, s);
                }
                else if (ms.name_override == ".ctor")
                {
                    // there are two constructors, choose the correct one
                    var pcount = ms.m.GetMethodDefSigParamCount(ms.msig);

                    if (pcount == ms.type.arr_rank)
                    {
                        code_override = ir.ConvertToIR.CreateArrayCtor1(ms, t, s);
                    }
                    else if (pcount == 2 * ms.type.arr_rank)
                    {
                        code_override = ir.ConvertToIR.CreateArrayCtor2(ms, t, s);
                    }
                    else
                    {
                        throw new NotSupportedException("Invalid number of parameters to " + ms.MangleMethod() + " for array of rank " + ms.type.arr_rank.ToString());
                    }
                }
                else if (ms.name_override == "Set")
                {
                    code_override = ir.ConvertToIR.CreateArraySet(ms, t, s);
                }
                else if (ms.name_override == "Address")
                {
                    code_override = ir.ConvertToIR.CreateArrayAddress(ms, t, s);
                }
                else
                {
                    throw new NotImplementedException(ms.name_override);
                }

                sym_st = binary_library.SymbolType.Weak;
            }

            /* Is this a vector method? */
            if (rva == 0 &&
                ms.type != null &&
                ms.type.stype == TypeSpec.SpecialType.SzArray &&
                code_override == null)
            {
                if (ms.Name == "IndexOf")
                {
                    code_override = ir.ConvertToIR.CreateVectorIndexOf(ms, t, s);
                }
                else if (ms.Name == "Insert")
                {
                    code_override = ir.ConvertToIR.CreateVectorInsert(ms, t, s);
                }
                else if (ms.Name == "RemoveAt")
                {
                    code_override = ir.ConvertToIR.CreateVectorRemoveAt(ms, t, s);
                }
                else if (ms.Name == "get_Item")
                {
                    code_override = ir.ConvertToIR.CreateVectorget_Item(ms, t, s);
                }
                else if (ms.Name == "set_Item")
                {
                    code_override = ir.ConvertToIR.CreateVectorset_Item(ms, t, s);
                }
                else if (ms.Name == "get_Count")
                {
                    code_override = ir.ConvertToIR.CreateVectorget_Count(ms, t, s);
                }
                else if (ms.Name == "CopyTo")
                {
                    code_override = ir.ConvertToIR.CreateVectorCopyTo(ms, t, s);
                }

                /*else if (ms.Name == "GetEnumerator")
                 *  code_override = ir.ConvertToIR.CreateVectorGetEnumerator(ms, t);*/
                else if (ms.Name == "Add" ||
                         ms.Name == "Clear" ||
                         ms.Name == "Contains" ||
                         ms.Name == "Remove" ||
                         ms.Name == "get_IsReadOnly" ||
                         ms.Name == "get_IsSynchronized" ||
                         ms.Name == "get_SyncRoot" ||
                         ms.Name == "get_IsFixedSize" ||
                         ms.Name == "Clone" ||
                         ms.Name == "CompareTo" ||
                         ms.Name == "GetHashCode" ||
                         ms.Name == "Equals")
                {
                    code_override = ir.ConvertToIR.CreateVectorUnimplemented(ms, t, s);
                }
                else
                {
                    return(false);
                }

                sym_st = binary_library.SymbolType.Weak;
            }

            if (rva == 0 && code_override == null)
            {
                return(false);
            }

            // Get mangled name for defining a symbol
            List <binary_library.ISymbol> meth_syms = new List <binary_library.ISymbol>();
            var mangled_name = m.MangleMethod(ms);
            var meth_sym     = bf.CreateSymbol();

            meth_sym.Name       = mangled_name;
            meth_sym.ObjectType = binary_library.SymbolObjectType.Function;
            meth_sym.Offset     = (ulong)ts.Data.Count;
            meth_sym.Type       = binary_library.SymbolType.Global;
            ts.AddSymbol(meth_sym);
            meth_syms.Add(meth_sym);

            foreach (var alias in ms.MethodAliases)
            {
                var alias_sym = bf.CreateSymbol();
                alias_sym.Name       = alias;
                alias_sym.ObjectType = binary_library.SymbolObjectType.Function;
                alias_sym.Offset     = (ulong)ts.Data.Count;
                alias_sym.Type       = binary_library.SymbolType.Global;
                ts.AddSymbol(alias_sym);
                meth_syms.Add(alias_sym);
            }

            if (ms.HasCustomAttribute("_ZN14libsupcs#2Edll8libsupcs20WeakLinkageAttribute_7#2Ector_Rv_P1u1t"))
            {
                sym_st = binary_library.SymbolType.Weak;
            }
            if (base_m != null && ms.m != base_m)
            {
                sym_st = binary_library.SymbolType.Weak;
            }
            foreach (var sym in meth_syms)
            {
                sym.Type = sym_st;
            }

            // Get signature if not specified
            if (csite == 0)
            {
                csite = (int)m.GetIntEntry(metadata.MetadataStream.tid_MethodDef,
                                           mdef, 4);
            }

            Code cil;

            if (code_override == null)
            {
                var meth = m.GetRVA(rva);

                var  flags        = meth.ReadByte(0);
                int  max_stack    = 0;
                long code_size    = 0;
                long lvar_sig_tok = 0;
                int  boffset      = 0;
                List <metadata.ExceptionHeader> ehdrs = null;
                bool has_exceptions = false;

                if ((flags & 0x3) == 0x2)
                {
                    // Tiny header
                    code_size = flags >> 2;
                    max_stack = 8;
                    boffset   = 1;
                }
                else if ((flags & 0x3) == 0x3)
                {
                    // Fat header
                    uint fat_flags   = meth.ReadUShort(0) & 0xfffU;
                    int  fat_hdr_len = (meth.ReadUShort(0) >> 12) * 4;
                    max_stack    = meth.ReadUShort(2);
                    code_size    = meth.ReadUInt(4);
                    lvar_sig_tok = meth.ReadUInt(8);
                    boffset      = fat_hdr_len;

                    if ((flags & 0x8) == 0x8)
                    {
                        has_exceptions = true;

                        ehdrs = new List <metadata.ExceptionHeader>();

                        int ehdr_offset = boffset + (int)code_size;
                        ehdr_offset = util.util.align(ehdr_offset, 4);

                        while (true)
                        {
                            int kind = meth.ReadByte(ehdr_offset);

                            if ((kind & 0x1) != 0x1)
                            {
                                throw new Exception("Invalid exception header");
                            }

                            bool is_fat = false;
                            if ((kind & 0x40) == 0x40)
                            {
                                is_fat = true;
                            }

                            int data_size = meth.ReadInt(ehdr_offset);
                            data_size >>= 8;
                            if (is_fat)
                            {
                                data_size &= 0xffffff;
                            }
                            else
                            {
                                data_size &= 0xff;
                            }

                            int clause_count;
                            if (is_fat)
                            {
                                clause_count = (data_size - 4) / 24;
                            }
                            else
                            {
                                clause_count = (data_size - 4) / 12;
                            }

                            ehdr_offset += 4;
                            for (int i = 0; i < clause_count; i++)
                            {
                                var ehdr = ParseExceptionHeader(meth,
                                                                ref ehdr_offset, is_fat, ms);
                                ehdr.EhdrIdx = i;
                                ehdrs.Add(ehdr);
                            }

                            if ((kind & 0x80) != 0x80)
                            {
                                break;
                            }
                        }
                    }
                }
                else
                {
                    throw new Exception("Invalid method header flags");
                }

                /* Parse CIL code */
                cil = libtysila5.cil.CilParser.ParseCIL(meth,
                                                        ms, boffset, (int)code_size, lvar_sig_tok,
                                                        has_exceptions, ehdrs);
                cil.s = s;

                /* Allocate local vars and args */
                t.AllocateLocalVarsArgs(cil);

                /* Convert to IR */
                cil.t = t;
                ir.ConvertToIR.DoConversion(cil);
            }
            else
            {
                cil = code_override;
            }


            /* Allocate registers */
            ir.AllocRegs.DoAllocation(cil);


            /* Choose instructions */
            target.ChooseInstructions.DoChoosing(cil);
            t.AssemblePass(cil);
            //((target.x86.x86_Assembler)cil.t).AssemblePass(cil);

            foreach (var sym in meth_syms)
            {
                sym.Size = ts.Data.Count - (int)sym.Offset;
            }

            foreach (var extra_sym in cil.extra_labels)
            {
                var esym = bf.CreateSymbol();
                esym.Name       = extra_sym.Name;
                esym.ObjectType = binary_library.SymbolObjectType.Function;
                esym.Offset     = (ulong)extra_sym.Offset;
                esym.Type       = sym_st;
                ts.AddSymbol(esym);
            }

            /* Dump debug */
            DumpDebug(debug_passes, meth_syms, cil);

            /* Signature table */
            if (data_sect == null)
            {
                data_sect = bf.GetDataSection();
            }
            s.sigt.WriteToOutput(bf, ms.m, t, data_sect);

            /* DWARF output */
            if (dcu != null)
            {
                var ddie = dcu.GetMethodDie(ms);
                ddie.sym = meth_syms[0];
                ddie.cil = cil;

                var ddts = dcu.GetTypeDie(ms.type) as dwarf.DwarfParentDIE;
                ddts.Children.Add(ddie);

                if (ms.ReturnType != null)
                {
                    dcu.GetTypeDie(ms.ReturnType);
                    if (ms.ReturnType.stype == TypeSpec.SpecialType.None && !ms.ReturnType.IsValueType)
                    {
                        dcu.GetTypeDie(ms.ReturnType.Pointer);
                    }
                }
                foreach (var la in cil.la_types)
                {
                    dcu.GetTypeDie(la);
                    if (la.stype == TypeSpec.SpecialType.None && !la.IsValueType)
                    {
                        dcu.GetTypeDie(la.Pointer);
                    }
                }
                foreach (var lv in cil.lv_types)
                {
                    dcu.GetTypeDie(lv);
                    if (lv.stype == TypeSpec.SpecialType.None && !lv.IsValueType)
                    {
                        dcu.GetTypeDie(lv.Pointer);
                    }
                }

                if (!ms.IsStatic)
                {
                    dcu.GetTypeDie(ms.type.Pointer);
                }

                // do we have source lines?
                if (ms.m.pdb != null && ms.mdrow > 0)
                {
                    var sps = ms.m.pdb.DebugGetSeqPtForMDRow(ms.mdrow);
                    if (sps != null && cil.cil != null && cil.cil.Count > 0)
                    {
                        /* Start building a Line Number Program
                         *
                         * We follow the example in DWARF4 D.5 (p251), with a few changes
                         *
                         * header - defined per CU
                         *   - add this/these source files to it if necessary
                         *
                         * DW_LNE_set_address - psize 0s, reloc to mangled name
                         * DW_LNS_advance_pc - mc_offset of first cil instruction
                         * DW_LNS_set_prologue_end
                         * DW_LNS_set_file - source file
                         * SPECIAL(0,0) - add first opcode
                         * SPECIAL(x,y) - add rest of opcodes
                         * DW_LNE_end_sequence
                         *
                         */

                        string cur_file = null;
                        int    cur_line = 1;
                        int    cur_mc   = 0;
                        int    cur_col  = 0;

                        var lnp = dcu.lnp;

                        // DW_LNE_set_address
                        lnp.AddRange(new byte[] { 0x00, (byte)(t.psize + 1), 0x02 });
                        dcu.lnp_relocs.Add(lnp.Count, meth_syms[0]);
                        for (int i = 0; i < t.psize; i++)
                        {
                            lnp.Add(0);
                        }

                        // DW_LNS_advance_pc
                        lnp.Add(0x02);
                        dwarf.DwarfDIE.w(lnp, (uint)cil.cil[0].mc_offset);
                        cur_mc = cil.cil[0].mc_offset;

                        // DW_LNS_set_prologue_end
                        lnp.Add(0x0a);

                        foreach (var cn in cil.cil)
                        {
                            var mc_advance = cn.mc_offset - cur_mc;

                            // get current line number
                            MetadataStream.SeqPt csp = null;
                            foreach (var sp in sps)
                            {
                                if (sp.IlOffset == cn.il_offset &
                                    !sp.IsHidden)
                                {
                                    csp = sp;
                                    break;
                                }
                            }
                            if (csp != null)
                            {
                                var line_advance = csp.StartLine - cur_line;

                                if (ddie.StartLine == 0)
                                {
                                    ddie.StartLine = csp.StartLine;
                                }
                                if (ddie.StartColumn == 0)
                                {
                                    ddie.StartColumn = csp.StartCol;
                                }

                                if (csp.DocName != cur_file)
                                {
                                    // DW_LNS_set_file
                                    lnp.Add(0x04);

                                    uint file_no;
                                    if (!dcu.lnp_files.TryGetValue(csp.DocName, out file_no))
                                    {
                                        file_no = (uint)(dcu.lnp_files.Count + 1);
                                        dcu.lnp_files[csp.DocName] = file_no;
                                        dcu.lnp_fnames.Add(csp.DocName);
                                    }
                                    if (ddie.SourceFileId == 0)
                                    {
                                        ddie.SourceFileId = (int)file_no;
                                    }

                                    dwarf.DwarfDIE.w(lnp, file_no);

                                    cur_file = csp.DocName;
                                }

                                if (csp.StartCol != cur_col)
                                {
                                    // DW_LNS_set_column
                                    lnp.Add(0x05);
                                    dwarf.DwarfDIE.w(lnp, (uint)csp.StartCol);
                                    cur_col = csp.StartCol;
                                }

                                /* SPECIAL if possible
                                 *  Use example on DWARF4 p132:
                                 *      opcode_base = 13, line_base = -3, line_range = 12
                                 *
                                 *  Gives a line advance range of [-3,8] and op_advance [0,19]
                                 */

                                if ((line_advance >= dcu.line_base && line_advance < (dcu.line_base + dcu.line_range)) &&
                                    (mc_advance >= 0 && mc_advance < dcu.mc_advance_max))
                                {
                                    var spec_opcode = (line_advance - dcu.line_base) +
                                                      (dcu.line_range * mc_advance) + dcu.opcode_base;
                                    lnp.Add((byte)spec_opcode);
                                }
                                else
                                {
                                    // DW_LNS_advance_pc
                                    lnp.Add(0x02);
                                    dwarf.DwarfDIE.w(lnp, (uint)mc_advance);

                                    // DW_LNS_advance_line
                                    lnp.Add(0x03);
                                    dwarf.DwarfDIE.w(lnp, line_advance);

                                    // SPECIAL(0,0)
                                    var spec_opcode = (0 - dcu.line_base) + dcu.opcode_base;
                                    lnp.Add((byte)spec_opcode);
                                }

                                cur_line += line_advance;
                                cur_mc   += mc_advance;
                            }
                        }

                        // Advance to end
                        var to_advance = (int)meth_syms[0].Size - cur_mc;
                        lnp.Add(0x02);
                        dwarf.DwarfDIE.w(lnp, to_advance);

                        // DW_LNE_end_sequence
                        lnp.Add(0x00);
                        lnp.Add(0x01);
                        lnp.Add(0x01);
                    }
                }
            }

            return(true);
        }
示例#6
0
 /** <summary>LEB128 encode data to output file</summary> */
 protected void w(binary_library.ISection s, uint data)
 {
     w(s.Data, data);
 }
示例#7
0
        /** Write standard abbreviations
         *    1  - compile_unit
         *    2  - base_type
         *    3  - pointer type (generic)
         *    4  - pointer type (with base type)
         *    5  - subprogram, returns void, static, non-virt
         *    6  - subprogram, returns object, static, non-virt
         *    7  - subprogram, returns void, instance, non-virt
         *    8  - subprogram, returns object, instance, non-virt
         *    9  - subprogram, returns void, instance, virtual
         *    10 - subprogram, returns object, instance, virtual
         *    11 - formal_parameter
         *    12 - namespace
         *    13 - class
         *    14 - structure
         *    15 - base_type
         *    16 - pointer
         *    17 - reference
         *    18 - member
         *    19 - formal_parameter with no name and artificial flag set
         *    20 - typedef
         *    21 - variable
         *    22 - method definition
         *    23 - class with decl_file/line/column
         *    24 - structure with decl_file/line/column
         */
        private void WriteAbbrev(binary_library.ISection abbrev)
        {
            uint dtype = t.psize == 4 ? 0x06U : 0x07U;  // data4/data 8 depending on target

            w(abbrev, new uint[]
            {
                1, 0x11, 0x01,      // compile_unit, has children
                0x25, 0x0e,         // producer, strp
                0x13, 0x0b,         // language, data1
                0x03, 0x0e,         // name, strp
                0x1b, 0x0e,         // comp_dir, strp
                0x11, 0x01,         // low_pc, addr
                0x12, dtype,        // high_pc, data (i.e. length)
                0x10, 0x17,         // stmt_list, sec_offset
                0x00, 0x00          // terminate
            });

            w(abbrev, new uint[]
            {
                2, 0x24, 0x00,      // base_type, no children
                0x0b, 0x0b,         // byte_size, data1
                0x3e, 0x0b,         // encoding, data1
                0x03, 0x0e,         // name, strp
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                3, 0x0f, 0x00,      // pointer_type, no children
                0x0b, 0x0b,         // byte_size, data1
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                4, 0x0f, 0x00,      // pointer_type, no children
                0x0b, 0x0b,         // byte_size, data1
                0x49, 0x15,         // type, LEB128 from start of CU in bytes
                0x00, 0x00,
            });

            w(abbrev, new uint[]
            {
                5, 0x2e, 0x01,      // subprogram, has children
                0x03, 0x0e,         // name, strp
                0x11, 0x01,         // low_pc, addr
                0x12, dtype,        // high_pc, data (i.e. length)
                0x32, 0x0b,         // accessibility, data1
                0x6e, 0x0e,         // linkage_name, strp
                0x3c, 0x19,         // declaration, present
                0x27, 0x19,         // prototyped, present
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                6, 0x2e, 0x01,      // subprogram, has children
                0x03, 0x0e,         // name, strp
                0x11, 0x01,         // low_pc, addr
                0x12, dtype,        // high_pc, data (i.e. length)
                0x32, 0x0b,         // accessibility, data1
                0x6e, 0x0e,         // linkage_name, strp
                0x49, 0x13,         // type, ref4
                0x3c, 0x19,         // declaration, present
                0x27, 0x19,         // prototyped, present
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                7, 0x2e, 0x01,      // subprogram, has children
                0x03, 0x0e,         // name, strp
                0x11, 0x01,         // low_pc, addr
                0x12, dtype,        // high_pc, data (i.e. length)
                0x32, 0x0b,         // accessibility, data1
                0x6e, 0x0e,         // linkage_name, strp
                0x64, 0x13,         // object_pointer, ref4
                0x3c, 0x19,         // declaration, present
                0x27, 0x19,         // prototyped, present
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                8, 0x2e, 0x01,      // subprogram, has children
                0x03, 0x0e,         // name, strp
                0x11, 0x01,         // low_pc, addr
                0x12, dtype,        // high_pc, data (i.e. length)
                0x32, 0x0b,         // accessibility, data1
                0x6e, 0x0e,         // linkage_name, strp
                0x49, 0x13,         // type, ref4
                0x64, 0x13,         // object_pointer, ref4
                0x3c, 0x19,         // declaration, present
                0x27, 0x19,         // prototyped, present
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                9, 0x2e, 0x01,      // subprogram, has children
                0x03, 0x0e,         // name, strp
                0x11, 0x01,         // low_pc, addr
                0x12, dtype,        // high_pc, data (i.e. length)
                0x32, 0x0b,         // accessibility, data1
                0x6e, 0x0e,         // linkage_name, strp
                0x64, 0x13,         // object_pointer, ref4
                0x4c, 0x0b,         // virtuality, data1
                0x3c, 0x19,         // declaration, present
                0x27, 0x19,         // prototyped, present
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                10, 0x2e, 0x01,     // subprogram, has children
                0x03, 0x0e,         // name, strp
                0x11, 0x01,         // low_pc, addr
                0x12, dtype,        // high_pc, data (i.e. length)
                0x32, 0x0b,         // accessibility, data1
                0x6e, 0x0e,         // linkage_name, strp
                0x49, 0x13,         // type, ref4
                0x64, 0x13,         // object_pointer, ref4
                0x4c, 0x0b,         // virtuality, data1
                0x3c, 0x19,         // declaration, present
                0x27, 0x19,         // prototyped, present
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                11, 0x05, 0x00,     // formal_parameter, no children
                0x03, 0x0e,         // name, strp
                0x49, 0x13,         // type, ref4
                0x02, 0x18,         // location, exprloc
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                12, 0x39, 0x01,     // namespace, has children
                0x03, 0x0e,         // name, strp
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                13, 0x02, 0x01,     // class, has children
                0x03, 0x0e,         // name, strp
                0x0b, 0x0f,         // byte_size, udata (LEB128)
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                14, 0x13, 0x01,     // structure, has children
                0x03, 0x0e,         // name, strp
                0x0b, 0x0f,         // byte_size, udata (LEB128)
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                15, 0x24, 0x00,     // base_type, no children
                0x03, 0x0e,         // name, strp
                0x0b, 0x0b,         // byte_size, data1
                0x3e, 0x0b,         // encoding, data1
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                16, 0x0f, 0x00,     // pointer_type, no children
                0x0b, 0x0b,         // byte_size, data1
                0x49, 0x13,         // type, ref4
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                17, 0x0f, 0x00,     // reference_type, no children
                0x0b, 0x0b,         // byte_size, data1
                0x49, 0x13,         // type, ref4
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                18, 0x0d, 0x00,     // member, no children
                0x03, 0x0e,         // name, strp
                0x49, 0x13,         // type, ref4
                0x38, 0x0f,         // data_member_location, udata (LEB128)
                0x00, 0x00,
            });

            w(abbrev, new uint[]
            {
                19, 0x05, 0x00,     // formal_parameter, no children
                0x49, 0x13,         // type, ref4
                0x34, 0x19,         // artificial, flag_present
                0x02, 0x18,         // location, exprloc
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                20, 0x16, 0x00,     // typedef, no children
                0x03, 0x0e,         // name, strp
                0x49, 0x13,         // type, ref4
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                21, 0x34, 0x00,     // variable, no children
                0x03, 0x0e,         // name, strp
                0x49, 0x13,         // type, ref4
                0x02, 0x18,         // location, exprloc
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                22, 0x2e, 0x01,     // subprogram, has children
                0x47, 0x13,         // specification, ref4
                0x11, 0x01,         // low_pc, addr
                0x12, dtype,        // high_pc, data (i.e. length)
                //0x64, 0x13,         // object_pointer, ref4
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                23, 0x02, 0x01,     // class, has children
                0x03, 0x0e,         // name, strp
                0x0b, 0x0f,         // byte_size, udata (LEB128)
                0x3a, 0x0b,         // decl_file, data1
                0x3b, 0x0b,         // decl_line, data1
                0x39, 0x0b,         // decl_column, data1
                0x00, 0x00,         // terminate
            });

            w(abbrev, new uint[]
            {
                24, 0x13, 0x01,     // structure, has children
                0x03, 0x0e,         // name, strp
                0x0b, 0x0f,         // byte_size, udata (LEB128)
                0x3a, 0x0b,         // decl_file, data1
                0x3b, 0x0b,         // decl_line, data1
                0x39, 0x0b,         // decl_column, data1
                0x00, 0x00,         // terminate
            });


            // last unit should have type 0
            w(abbrev, new uint[]
            {
                0x00, 0x00
            });
        }
示例#8
0
        public static void OutputEHdr(MethodSpecWithEhdr ms,
                                      Target t, binary_library.IBinaryFile of,
                                      TysilaState s,
                                      MetadataStream base_m      = null,
                                      binary_library.ISection os = null)
        {
            // Don't compile if not for this architecture
            if (!t.IsMethodValid(ms.ms))
            {
                return;
            }

            if (os == null)
            {
                os = of.GetRDataSection();
            }
            os.Align(t.GetPointerSize());
            var d = os.Data;

            /* Symbol */
            var sym = of.CreateSymbol();

            sym.Name       = ms.ms.MangleMethod() + "EH";
            sym.ObjectType = binary_library.SymbolObjectType.Object;
            sym.Offset     = (ulong)d.Count;
            sym.Type       = binary_library.SymbolType.Global;
            os.AddSymbol(sym);

            if (base_m != null && ms.ms.m != base_m)
            {
                sym.Type = binary_library.SymbolType.Weak;
            }

            foreach (var ehdr in ms.c.ehdrs)
            {
                var v = t.IntPtrArray(BitConverter.GetBytes((int)ehdr.EType));
                foreach (var b in v)
                {
                    d.Add(b);
                }

                /* Handler */
                var hand_sym = of.CreateSymbol();
                hand_sym.Name = ms.ms.MangleMethod() + "EH" + ehdr.EhdrIdx.ToString();

                var hand_reloc = of.CreateRelocation();
                hand_reloc.Addend     = 0;
                hand_reloc.DefinedIn  = os;
                hand_reloc.Offset     = (ulong)d.Count;
                hand_reloc.References = hand_sym;
                hand_reloc.Type       = t.GetDataToCodeReloc();
                of.AddRelocation(hand_reloc);

                for (int i = 0; i < t.GetPointerSize(); i++)
                {
                    d.Add(0);
                }

                /* Catch object */
                if (ehdr.ClassToken != null)
                {
                    var catch_sym = of.CreateSymbol();
                    catch_sym.Name = ehdr.ClassToken.MangleType();

                    var catch_reloc = of.CreateRelocation();
                    catch_reloc.Addend     = 0;
                    catch_reloc.DefinedIn  = os;
                    catch_reloc.Offset     = (ulong)d.Count;
                    catch_reloc.References = catch_sym;
                    catch_reloc.Type       = t.GetDataToDataReloc();
                    of.AddRelocation(catch_reloc);

                    s.r.VTableRequestor.Request(ehdr.ClassToken);
                }
                else if (ehdr.EType == ExceptionHeader.ExceptionHeaderType.Filter)
                {
                    var filt_sym = of.CreateSymbol();
                    filt_sym.Name = ms.ms.MangleMethod() + "EHF" + ehdr.EhdrIdx.ToString();

                    var filt_reloc = of.CreateRelocation();
                    filt_reloc.Addend     = 0;
                    filt_reloc.DefinedIn  = os;
                    filt_reloc.Offset     = (ulong)d.Count;
                    filt_reloc.References = filt_sym;
                    filt_reloc.Type       = t.GetDataToCodeReloc();
                    of.AddRelocation(filt_reloc);
                }
                for (int i = 0; i < t.GetPointerSize(); i++)
                {
                    d.Add(0);
                }
            }

            sym.Size = (long)((ulong)d.Count - sym.Offset);
        }