public override void WriteToOutput(DwarfSections ds, IList <byte> d, DwarfDIE parent) { d.Add((byte)12); w(d, ns, ds.smap); base.WriteToOutput(ds, d, parent); }
public override void WriteToOutput(DwarfSections ds, IList <byte> d, DwarfDIE parent) { w(d, 21); w(d, name, ds.smap); dcu.fmap[d.Count] = dcu.GetTypeDie(ts); for (int i = 0; i < 4; i++) { d.Add(0); } // location as exprloc var b = new List <byte>(); if (t.AddDwarfLocation(loc, b)) { DwarfDIE.w(d, (uint)b.Count); foreach (var c in b) { d.Add(c); } } else { throw new NotImplementedException(); } }
public override void WriteToOutput(DwarfSections ds, IList <byte> d, DwarfDIE parent) { w(d, 22); dcu.fmap[d.Count] = decl; for (int i = 0; i < 4; i++) { d.Add(0); } var low_r = ds.bf.CreateRelocation(); low_r.Type = t.GetDataToDataReloc(); low_r.Offset = (ulong)d.Count; low_r.References = ds.bf.FindSymbol(decl.ms.MangleMethod()); low_r.DefinedIn = ds.info; ds.bf.AddRelocation(low_r); wp(d); // low_pc wp(d, low_r.References.Size); // high_pc foreach (var child in decl.Children) { child.WriteToOutput(ds, d, this); } d.Add(0); }
public override void WriteToOutput(DwarfSections ds, IList <byte> dinfo, DwarfDIE parent) { foreach (var c in Children) { c.Offset = dinfo.Count; c.WriteToOutput(ds, dinfo, this); } dinfo.Add(0); // null-terminate }
public override void WriteToOutput(DwarfSections ds, IList <byte> d, DwarfDIE parent) { d.Add(18); w(d, Name, ds.smap); dcu.fmap[d.Count] = FieldType; for (int i = 0; i < 4; i++) { d.Add(0); } w(d, (uint)FieldOffset); }
public void WriteToOutput(DwarfSections odbgsect) { WriteAbbrev(odbgsect.abbrev); WriteInfo(odbgsect); odbgsect.smap.Write(odbgsect.str); WriteLines(odbgsect); WritePubTypes(odbgsect); WritePubNames(odbgsect); }
private void WriteInfo(DwarfSections ds) { var info = ds.info; var string_map = ds.smap; List <byte> d = new List <byte>(); // Output header // Reserve space for unit_length if (t.psize == 4) { for (int i = 0; i < 4; i++) { d.Add(0); } } else { for (int i = 0; i < 12; i++) { d.Add(0); } } // version d.Add(4); d.Add(0); // debug_abbrev_offset for (int i = 0; i < t.psize; i++) { d.Add(0); } // address_size d.Add((byte)t.psize); // Store offset of root entry this.Offset = d.Count; // Write the root DIE w(d, 1); w(d, "tysila", string_map); w(d, 0x4); // pretend to be C++ var fname = m.file.Name; if (fname == null || fname.Equals(string.Empty)) { w(d, m.AssemblyName, string_map); w(d, "", string_map); } else { var finfo = new System.IO.FileInfo(fname); w(d, finfo.Name, string_map); w(d, finfo.DirectoryName, string_map); } // store low/high pc offsets for patching later var low_pc_offset = d.Count; for (int i = 0; i < t.psize; i++) { d.Add(0); } var high_pc_offset = d.Count; for (int i = 0; i < t.psize; i++) { d.Add(0); } var stmt_list_offset = d.Count; for (int i = 0; i < t.psize; i++) { d.Add(0); } /* Children: * Items in the empty namespace are placed as direct children * Others are placed as children of the namespace */ foreach (var kvp in ns_dies) { if (kvp.Key == "") { foreach (var dc in kvp.Value.Children) { Children.Add(dc); } } else { Children.Add(kvp.Value); } } /* Add defintions for all the methods in the main namespace */ foreach (var methkvp in method_dies) { var methdef = new DwarfMethodDefDIE(); methdef.dcu = this; methdef.t = t; methdef.decl = methkvp.Value; Children.Add(methdef); } // Write children base.WriteToOutput(ds, d, null); // Patch relocs byte[] bytes; foreach (var kvp in fmap) { uint dest = (uint)kvp.Value.Offset; int addr = kvp.Key; bytes = BitConverter.GetBytes(dest); for (int i = 0; i < 4; i++) { d[addr + i] = bytes[i]; } } // Patch low/high_pc var low_r = ds.bf.CreateRelocation(); low_r.Type = t.GetDataToDataReloc(); low_r.Offset = (ulong)low_pc_offset; low_r.References = first_sym; low_r.DefinedIn = ds.info; ds.bf.AddRelocation(low_r); var pc_size = last_sym.Offset - first_sym.Offset + (ulong)last_sym.Size; bytes = (t.psize == 4) ? BitConverter.GetBytes((int)pc_size) : BitConverter.GetBytes((long)pc_size); for (int i = 0; i < t.psize; i++) { d[high_pc_offset + i] = bytes[i]; } // Finally, patch the length back in if (t.psize == 4) { uint len = (uint)d.Count - 4; bytes = BitConverter.GetBytes(len); for (int i = 0; i < 4; i++) { d[i] = bytes[i]; } } else { ulong len = (ulong)d.Count - 12; bytes = BitConverter.GetBytes(len); for (int i = 0; i < 4; i++) { d[i] = 0xff; } for (int i = 0; i < 8; i++) { d[i + 4] = bytes[i]; } } // Store to section for (int i = 0; i < d.Count; i++) { info.Data.Add(d[i]); } }
private void WriteLines(DwarfSections odbgsect) { /* Write lines header */ List <byte> d = new List <byte>(); // Reserve space for unit_length if (t.psize == 4) { for (int i = 0; i < 4; i++) { d.Add(0); } } else { for (int i = 0; i < 12; i++) { d.Add(0); } } // version d.Add(4); d.Add(0); // header_length var header_length_offset = d.Count; for (int i = 0; i < t.psize; i++) { d.Add(0); } // minimum_instruction_length d.Add(1); // maximum_operations_per_instruction d.Add(1); // default_is_stmt d.Add(1); // line_base if (line_base < 0) { d.Add((byte)(0x100 + line_base)); } else { d.Add((byte)line_base); } // line_range d.Add((byte)line_range); // opcode_base d.Add((byte)opcode_base); // standard_opcode_lengths d.AddRange(new byte[] { 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 }); // include_directories d.Add(0); // file_names foreach (var fname in lnp_fnames) { foreach (var c in fname) { d.Add((byte)c); } d.Add(0); // dir index d.Add(0); // last_mod d.Add(0); // length d.Add(0); } d.Add(0); // point header_length here var doffset = d.Count; var header_length = doffset - header_length_offset - t.psize; byte[] bytes = (t.psize == 4) ? BitConverter.GetBytes((int)header_length) : BitConverter.GetBytes((long)header_length); for (int i = 0; i < t.psize; i++) { d[header_length_offset + i] = bytes[i]; } // add the actual data d.AddRange(lnp); // add relocs foreach (var reloc in lnp_relocs) { var r = odbgsect.bf.CreateRelocation(); r.Type = t.GetDataToDataReloc(); r.Offset = (ulong)(doffset + reloc.Key); r.References = reloc.Value; r.DefinedIn = odbgsect.line; odbgsect.bf.AddRelocation(r); } // Finally, patch the length back in if (t.psize == 4) { uint len = (uint)d.Count - 4; bytes = BitConverter.GetBytes(len); for (int i = 0; i < 4; i++) { d[i] = bytes[i]; } } else { ulong len = (ulong)d.Count - 12; bytes = BitConverter.GetBytes(len); for (int i = 0; i < 4; i++) { d[i] = 0xff; } for (int i = 0; i < 8; i++) { d[i + 4] = bytes[i]; } } // Store to section for (int i = 0; i < d.Count; i++) { odbgsect.line.Data.Add(d[i]); } }
private void WritePubNames(DwarfSections odbgsect) { /* Write lines header */ List <byte> d = new List <byte>(); // Reserve space for unit_length if (t.psize == 4) { for (int i = 0; i < 4; i++) { d.Add(0); } } else { for (int i = 0; i < 12; i++) { d.Add(0); } } // version d.Add(2); d.Add(0); // debug_info_offset for (int i = 0; i < t.psize; i++) { d.Add(0); } // debug_info_length var length = odbgsect.info.Data.Count; var bytes = (t.psize == 4) ? BitConverter.GetBytes((int)length) : BitConverter.GetBytes((long)length); foreach (var b in bytes) { d.Add(b); } foreach (var kvp in method_dies) { // offset bytes = (t.psize == 4) ? BitConverter.GetBytes((int)kvp.Value.Offset) : BitConverter.GetBytes((long)kvp.Value.Offset); foreach (var b in bytes) { d.Add(b); } // name foreach (var c in kvp.Key.MangleMethod()) { d.Add((byte)c); } d.Add(0); } // Finally, patch the length back in if (t.psize == 4) { uint len = (uint)d.Count - 4; bytes = BitConverter.GetBytes(len); for (int i = 0; i < 4; i++) { d[i] = bytes[i]; } } else { ulong len = (ulong)d.Count - 12; bytes = BitConverter.GetBytes(len); for (int i = 0; i < 4; i++) { d[i] = 0xff; } for (int i = 0; i < 8; i++) { d[i + 4] = bytes[i]; } } // Store to section for (int i = 0; i < d.Count; i++) { odbgsect.pubnames.Data.Add(d[i]); } }
public abstract void WriteToOutput(DwarfSections ds, IList <byte> d, DwarfDIE parent);
public override void WriteToOutput(DwarfSections ds, IList <byte> d, DwarfDIE parent) { var ms = cil.ms; int abbrev = 5; if (ms.ReturnType != null) { abbrev += 1; } if (!ms.IsStatic) { abbrev += 2; if (ms.IsVirtual) { abbrev += 2; } } d.Add((byte)abbrev); w(d, ms.Name, ds.smap); var low_r = ds.bf.CreateRelocation(); low_r.Type = t.GetDataToDataReloc(); low_r.Offset = (ulong)d.Count; low_r.References = ds.bf.FindSymbol(ms.MangleMethod()); low_r.DefinedIn = ds.info; ds.bf.AddRelocation(low_r); wp(d); // low_pc wp(d, low_r.References.Size); // high_pc // Update first/last sym if necessary if (dcu.first_sym == null || low_r.References.Offset < dcu.first_sym.Offset) { dcu.first_sym = low_r.References; } if (dcu.last_sym == null || low_r.References.Offset > dcu.last_sym.Offset) { dcu.last_sym = low_r.References; } var mflags = ms.m.GetIntEntry(metadata.MetadataStream.tid_MethodDef, ms.mdrow, 2); var access = mflags & 0x07; if (access == 0x6) { d.Add(0x1); // public } else if (access >= 0x4) { d.Add(0x2); // protected } else { d.Add(0x3); // private } w(d, ms.MangleMethod(), ds.smap); if (ms.ReturnType != null) { dcu.fmap[d.Count] = (ms.ReturnType.stype == metadata.TypeSpec.SpecialType.None && !ms.ReturnType.IsValueType) ? dcu.GetTypeDie(ms.ReturnType.Pointer) : dcu.GetTypeDie(ms.ReturnType); // add return type for (int i = 0; i < 4; i++) { d.Add(0); } } int fparam_ref_loc = 0; if (!ms.IsStatic) { // reference for first parameter fparam_ref_loc = d.Count; for (int i = 0; i < 4; i++) { d.Add(0); } } if (ms.IsVirtual) { d.Add(0x1); // virtual } // Add parameters int sig_idx = ms.mdrow == 0 ? ms.msig : (int)ms.m.GetIntEntry(metadata.MetadataStream.tid_MethodDef, ms.mdrow, 4); var pc_nonthis = ms.m.GetMethodDefSigParamCount(sig_idx); var rt_idx = ms.m.GetMethodDefSigRetTypeIndex(sig_idx); ms.m.GetTypeSpec(ref rt_idx, ms.gtparams, ms.gmparams); if (ms.m.GetMethodDefSigHasNonExplicitThis(ms.msig)) { var fparam = new DwarfParamDIE(); fparam.dcu = dcu; fparam.t = t; fparam.IsThis = true; fparam.ts = ms.type.Pointer; Children.Add(fparam); } for (int i = 0; i < pc_nonthis; i++) { var fparam = new DwarfParamDIE(); fparam.dcu = dcu; fparam.t = t; fparam.IsThis = false; fparam.ts = ms.m.GetTypeSpec(ref rt_idx, ms.gtparams, ms.gmparams); if (fparam.ts.stype == metadata.TypeSpec.SpecialType.None && !fparam.ts.IsValueType) { fparam.ts = fparam.ts.Pointer; } Children.Add(fparam); } // Get param names if (ms.mdrow != 0) { int param_start = (int)ms.m.GetIntEntry(metadata.MetadataStream.tid_MethodDef, ms.mdrow, 5); int param_last_row = ms.m.GetRowCount(metadata.MetadataStream.tid_Param); int next_param = int.MaxValue; if (ms.mdrow < ms.m.GetRowCount(metadata.MetadataStream.tid_MethodDef)) { next_param = (int)ms.m.GetIntEntry(metadata.MetadataStream.tid_MethodDef, ms.mdrow + 1, 5) - 1; } int param_end = param_last_row > next_param ? next_param : param_last_row; for (int i = param_start; i <= param_end; i++) { var seq = ms.m.GetIntEntry(metadata.MetadataStream.tid_Param, i, 1); var name = ms.m.GetStringEntry(metadata.MetadataStream.tid_Param, i, 2); seq--; if (ms.m.GetMethodDefSigHasNonExplicitThis(ms.msig)) { seq++; } ((DwarfParamDIE)Children[(int)seq]).name = name; } } if (!ms.IsStatic) { // Patch the .this pointer to the first child dcu.fmap[fparam_ref_loc] = Children[0]; } // Param locations if (cil != null && cil.la_locs != null && cil.la_locs.Length == Children.Count) { for (int i = 0; i < cil.la_locs.Length; i++) { ((DwarfParamDIE)Children[i]).loc = cil.la_locs[i]; } } // Get param names if (ms.mdrow != 0) { string[] pnames = new string[cil.lv_types.Length]; if (ms.m.pdb != null) { for (int i = 1; i < ms.m.pdb.table_rows[(int)metadata.MetadataStream.TableId.LocalScope]; i++) { var lv_mdrow = (int)ms.m.pdb.GetIntEntry((int)metadata.MetadataStream.TableId.LocalScope, i, 0); if (lv_mdrow == ms.mdrow) { var lv_start = (int)ms.m.pdb.GetIntEntry((int)metadata.MetadataStream.TableId.LocalScope, i, 2); int lv_last_row = ms.m.pdb.GetRowCount((int)metadata.MetadataStream.TableId.LocalVariable); int next_lv = int.MaxValue; if (i < ms.m.pdb.GetRowCount((int)metadata.MetadataStream.TableId.LocalScope)) { next_lv = (int)ms.m.pdb.GetIntEntry((int)metadata.MetadataStream.TableId.LocalScope, i + 1, 2) - 1; } int lv_end = lv_last_row > next_lv ? next_lv : lv_last_row; for (int j = lv_start; j <= lv_end; j++) { var pindex = (int)ms.m.pdb.GetIntEntry((int)metadata.MetadataStream.TableId.LocalVariable, j, 1); var pname = ms.m.pdb.GetStringEntry((int)metadata.MetadataStream.TableId.LocalVariable, j, 2); pnames[pindex] = pname; } } } } for (int i = 0; i < pnames.Length; i++) { var pname = pnames[i]; if (pname != null) { var ptype = cil.lv_types[i]; var ploc = cil.lv_locs[i]; var vparam = new DwarfVarDIE(); vparam.dcu = dcu; vparam.t = t; vparam.ts = ptype; vparam.name = pname; vparam.loc = ploc; if (vparam.ts.stype == metadata.TypeSpec.SpecialType.None && !vparam.ts.IsValueType) { vparam.ts = vparam.ts.Pointer; } Children.Add(vparam); } } } base.WriteToOutput(ds, d, parent); }
public override void WriteToOutput(DwarfSections ds, IList <byte> d, DwarfDIE parent) { switch (stype) { case 0x02: // bool d.Add(15); w(d, "bool", ds.smap); d.Add((byte)t.GetSize(dcu.m.SystemBool)); d.Add(0x07); // unsigned break; case 0x03: // Char d.Add(15); w(d, "char", ds.smap); d.Add(2); d.Add(0x06); // signed char break; case 0x04: // I1 d.Add(15); w(d, "sbyte", ds.smap); d.Add(1); d.Add(0x05); // signed break; case 0x05: // U1 d.Add(15); w(d, "byte", ds.smap); d.Add(1); d.Add(0x07); // unsigned break; case 0x06: // I2 d.Add(15); w(d, "short", ds.smap); d.Add(2); d.Add(0x05); // signed break; case 0x07: // U2 d.Add(15); w(d, "ushort", ds.smap); d.Add(2); d.Add(0x07); // unsigned break; case 0x08: // I4 d.Add(15); w(d, "int", ds.smap); d.Add(4); d.Add(0x05); // signed break; case 0x09: // U4 d.Add(15); w(d, "uint", ds.smap); d.Add(4); d.Add(0x07); // unsigned break; case 0x0a: // I8 d.Add(15); w(d, "long", ds.smap); d.Add(8); d.Add(0x05); // signed break; case 0x0b: // U8 d.Add(15); w(d, "ulong", ds.smap); d.Add(8); d.Add(0x07); // unsigned break; case 0x0c: // R4 d.Add(15); w(d, "float", ds.smap); d.Add(4); d.Add(0x04); // float break; case 0x0d: // R8 d.Add(15); w(d, "double", ds.smap); d.Add(8); d.Add(0x04); // float break; default: throw new NotImplementedException(); } }
private void WriteBaseType(int st, DwarfSections ds, IList <byte> d, DwarfDIE parent) { if (parent is DwarfNSDIE && ((DwarfNSDIE)parent).ns == "System" && dcu.basetype_dies.ContainsKey(st)) { // These are typedefs to types in the global scope d.Add(20); w(d, ts.Name, ds.smap); dcu.fmap[d.Count] = dcu.basetype_dies[st]; for (int i = 0; i < 4; i++) { d.Add(0); } if (st == 0x1c) { System.Diagnostics.Debugger.Break(); } } else { /* There are a few CLI basetypes that do not have C# equivalents * or this is a string/object in the main namespace */ switch (st) { case 0x11: // ValueType // class_type d.Add(13); w(d, "ValueType", ds.smap); w(d, (uint)t.GetSize(ts)); base.WriteToOutput(ds, d, parent); break; case 0x18: // IntPtr d.Add(20); w(d, "IntPtr", ds.smap); dcu.fmap[d.Count] = dcu.basetype_dies[t.psize == 4 ? 0x08 : 0x0a]; for (int i = 0; i < 4; i++) { d.Add(0); } break; case 0x19: // IntPtr d.Add(20); w(d, "UIntPtr", ds.smap); dcu.fmap[d.Count] = dcu.basetype_dies[t.psize == 4 ? 0x09 : 0x0b]; for (int i = 0; i < 4; i++) { d.Add(0); } break; case 0x0e: // String // class_type d.Add(13); w(d, NameOverride ?? "String", ds.smap); w(d, 0); // size - TODO base.WriteToOutput(ds, d, parent); break; case 0x1c: // Object // class_type d.Add(13); w(d, NameOverride ?? "Object", ds.smap); w(d, (uint)t.GetSize(ts)); base.WriteToOutput(ds, d, parent); break; default: throw new NotImplementedException(); } } }
public override void WriteToOutput(DwarfSections ds, IList <byte> d, DwarfDIE parent) { int abbrev; // decide upon type switch (ts.stype) { case metadata.TypeSpec.SpecialType.Ptr: case metadata.TypeSpec.SpecialType.MPtr: d.Add(16); d.Add((byte)t.psize); dcu.fmap[d.Count] = dcu.GetTypeDie(ts.other); for (int i = 0; i < 4; i++) { d.Add(0); } break; case metadata.TypeSpec.SpecialType.Array: throw new NotImplementedException(); case metadata.TypeSpec.SpecialType.SzArray: throw new NotImplementedException(); case metadata.TypeSpec.SpecialType.None: if (ts.SimpleType != 0) { // base_type WriteBaseType(ts.SimpleType, ds, d, parent); } else if (ts.IsValueType && (ts.m == dcu.m)) { if (ts.m == dcu.m) { // structure_type var source_loc = GetSourceLoc(); if (source_loc == null) { d.Add(14); } else { d.Add(24); } w(d, ts.Name, ds.smap); w(d, (uint)t.GetSize(ts)); if (source_loc != null) { d.Add((byte)source_loc.file); d.Add((byte)source_loc.line); d.Add((byte)source_loc.col); } base.WriteToOutput(ds, d, parent); } else { // structure_type external throw new NotImplementedException(); } } else { if (ts.m == dcu.m) { // class_type var source_loc = GetSourceLoc(); if (source_loc == null) { d.Add(13); } else { d.Add(23); } w(d, ts.Name, ds.smap); w(d, (uint)t.GetSize(ts)); if (source_loc != null) { d.Add((byte)source_loc.file); d.Add((byte)source_loc.line); d.Add((byte)source_loc.col); } base.WriteToOutput(ds, d, parent); } else { // class_type external throw new NotImplementedException(); } } break; default: throw new NotImplementedException(); } }