public void Write(binary_library.ISection str) { foreach (var c in d) { str.Data.Add(c); } }
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; }
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"); }
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); }
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); }
/** <summary>LEB128 encode data to output file</summary> */ protected void w(binary_library.ISection s, uint data) { w(s.Data, data); }
/** 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 }); }
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); }