public SmxDebugLinesTable(FileHeader file, SectionEntry header) : base(file, header) { entries_ = DebugLineEntry.From(file.SectionReader(header), header); }
public SmxDebugSymbolsTable(FileHeader file, SectionEntry header, SmxDebugInfoSection info, SmxNameTable names) : base(file, header) { entries_ = DebugSymbolEntry.From(file, file.SectionReader(header), info, names); }
public SmxDataSection(FileHeader file, SectionEntry header) : base(file, header) { dh_ = DataHeader.From(file.SectionReader(header)); }
public SmxDebugInfoSection(FileHeader file, SectionEntry header) : base(file, header) { info_ = DebugInfoHeader.From(file.SectionReader(header)); }
public int Size; // Size of the dimension. public static DebugSymbolDimEntry[] From(FileHeader hdr, BinaryReader rd, int count) { var entries = new DebugSymbolDimEntry[count]; for (var i = 0; i < count; i++) { var entry = new DebugSymbolDimEntry(); // There's a padding of 2 bytes before this short. if (hdr != null && hdr.debugUnpacked) rd.ReadBytes(2); entry.tagid = rd.ReadUInt16(); entry.Size = rd.ReadInt32(); entries[i] = entry; } return entries; }
public SmxPubvarTable(FileHeader file, SectionEntry header, SmxNameTable names) : base(file, header) { pubvars_ = PubvarEntry.From(file.SectionReader(header), header, names); }
public SmxNativeTable(FileHeader file, SectionEntry header, SmxNameTable names) : base(file, header) { natives_ = NativeEntry.From(file.SectionReader(header), header, names); }
public SmxRttiListTable(FileHeader file, SectionEntry header, SmxNameTable names) : base(file, header) { var reader = file.SectionReader(header); }
public SmxSection(FileHeader file, SectionEntry header) { file_ = file; header_ = header; }
public static FileHeader From(BinaryReader rd) { var header = new FileHeader(); var header_bytes = rd.ReadBytes(Size); using (var stream = new MemoryStream(header_bytes)) using (var header_reader = new BinaryReader(stream)) { header.Magic = header_reader.ReadUInt32(); if (header.Magic != FILE_MAGIC) throw new Exception("invalid file magic value"); header.Version = header_reader.ReadUInt16(); header.Compression = (CompressionType)header_reader.ReadByte(); header.DiskSize = header_reader.ReadInt32(); if (header.DiskSize < Size) throw new Exception("invalid disksize"); header.ImageSize = header_reader.ReadInt32(); if (header.ImageSize < header.DiskSize) throw new Exception("invalid imagesize"); header.num_sections = header_reader.ReadByte(); header.stringtab = header_reader.ReadInt32(); if (header.stringtab < Size) throw new Exception("invalid string table value"); header.dataoffs = header_reader.ReadInt32(); if (header.dataoffs < Size) throw new Exception("invalid data offset value"); } // Set up the memory buffer we'll read from. header.Data = new byte[header.ImageSize]; Array.Copy(header_bytes, header.Data, Size); switch (header.Compression) { case CompressionType.None: // This case is easy... we can just read the rest of the file. rd.Read(header.Data, Size, header.ImageSize - Size); break; case CompressionType.Gz: { // Read the delta stuff in between dataoffs and here. rd.Read(header.Data, Size, header.dataoffs - Size); // Read the compressed buffer. Note when constructing the deflate // stream, we elide the first two header bytes since C# barfs on // them. var gzbytes = rd.ReadBytes(header.DiskSize - header.dataoffs); using (var gzstream = new MemoryStream(gzbytes, 2, gzbytes.Length - 2)) using (var deflate = new DeflateStream(gzstream, CompressionMode.Decompress)) using (var gz_reader = new BinaryReader(deflate)) { gz_reader.Read(header.Data, header.dataoffs, header.ImageSize - header.dataoffs); } // Swap out the reader. var new_stream = new MemoryStream(header.Data, Size, header.ImageSize - Size); rd = new BinaryReader(new_stream); break; } default: throw new Exception("unknown compression type"); } // Read section information. header.Sections = new SectionEntry[header.num_sections]; bool foundDbgNativesSection = false; for (var i = 0; i < header.num_sections; i++) { var entry = new SectionEntry(); entry.nameoffs = rd.ReadInt32(); if (entry.nameoffs < 0) throw new Exception("section name offset overflow"); entry.dataoffs = rd.ReadInt32(); if (entry.dataoffs < Size) throw new Exception("section data offset overflow"); entry.Size = rd.ReadInt32(); if (entry.Size < 0) throw new Exception("section size overflow"); entry.Name = header.string_at(entry.nameoffs); // Remember that there's a .dbg.natives section in the file. if (entry.Name == ".dbg.natives") foundDbgNativesSection = true; header.Sections[i] = entry; } // There was a brief period of incompatibility, where version == 0x0101 // and the packing changed, at the same time .dbg.natives was introduced. // Once the incompatibility was noted, version was bumped to 0x0102. header.debugUnpacked = (header.Version == SP1_VERSION_1_0) && !foundDbgNativesSection; return header; }
public SmxFile(BinaryReader br) { Header = FileHeader.From(br); // Parse precursor sections. foreach (var section in Header.Sections) { if (section.Name == ".names") { Names = new SmxNameTable(Header, section); } else if (section.Name == ".dbg.strings") { DebugNames = new SmxNameTable(Header, section); } else if (section.Name == ".dbg.info") { DebugInfo = new SmxDebugInfoSection(Header, section); } } // Parse out other sections. var unknown = new List <SectionEntry>(); foreach (var section in Header.Sections) { switch (section.Name) { case ".names": case ".dbg.strings": case ".dbg.info": break; case ".natives": Natives = new SmxNativeTable(Header, section, Names); break; case ".publics": Publics = new SmxPublicTable(Header, section, Names); break; case ".pubvars": Pubvars = new SmxPubvarTable(Header, section, Names); break; case ".tags": Tags = new SmxTagTable(Header, section, Names); break; case ".data": Data = new SmxDataSection(Header, section); break; case ".code": CodeV1 = new SmxCodeV1Section(Header, section); break; case ".dbg.files": DebugFiles = new SmxDebugFilesTable(Header, section, DebugNames); break; case ".dbg.lines": DebugLines = new SmxDebugLinesTable(Header, section); break; case ".dbg.natives": DebugNatives = new SmxDebugNativesTable(Header, section, DebugNames); break; case ".dbg.symbols": DebugSymbols = new SmxDebugSymbolsTable(Header, section, DebugInfo, DebugNames); break; default: unknown.Add(section); break; } } UnknownSections = unknown.ToArray(); }
public static FileHeader From(BinaryReader rd) { var header = new FileHeader(); var header_bytes = rd.ReadBytes(Size); using (var stream = new MemoryStream(header_bytes)) using (var header_reader = new BinaryReader(stream)) { header.Magic = header_reader.ReadUInt32(); if (header.Magic != FILE_MAGIC) { throw new Exception("invalid file magic value"); } header.Version = header_reader.ReadUInt16(); header.Compression = (CompressionType)header_reader.ReadByte(); header.DiskSize = header_reader.ReadInt32(); if (header.DiskSize < Size) { throw new Exception("invalid disksize"); } header.ImageSize = header_reader.ReadInt32(); if (header.ImageSize < header.DiskSize) { throw new Exception("invalid imagesize"); } header.num_sections = header_reader.ReadByte(); header.stringtab = header_reader.ReadInt32(); if (header.stringtab < Size) { throw new Exception("invalid string table value"); } header.dataoffs = header_reader.ReadInt32(); if (header.dataoffs < Size) { throw new Exception("invalid data offset value"); } } // Set up the memory buffer we'll read from. header.Data = new byte[header.ImageSize]; Array.Copy(header_bytes, header.Data, Size); switch (header.Compression) { case CompressionType.None: // This case is easy... we can just read the rest of the file. rd.Read(header.Data, Size, header.ImageSize - Size); break; case CompressionType.Gz: { // Read the delta stuff in between dataoffs and here. rd.Read(header.Data, Size, header.dataoffs - Size); // Read the compressed buffer. Note when constructing the deflate // stream, we elide the first two header bytes since C# barfs on // them. var gzbytes = rd.ReadBytes(header.DiskSize - header.dataoffs); using (var gzstream = new MemoryStream(gzbytes, 2, gzbytes.Length - 2)) using (var deflate = new DeflateStream(gzstream, CompressionMode.Decompress)) using (var gz_reader = new BinaryReader(deflate)) { gz_reader.Read(header.Data, header.dataoffs, header.ImageSize - header.dataoffs); } // Swap out the reader. var new_stream = new MemoryStream(header.Data, Size, header.ImageSize - Size); rd = new BinaryReader(new_stream); break; } default: throw new Exception("unknown compression type"); } // Read section information. header.Sections = new SectionEntry[header.num_sections]; bool foundDbgNativesSection = false; for (var i = 0; i < header.num_sections; i++) { var entry = new SectionEntry(); entry.nameoffs = rd.ReadInt32(); if (entry.nameoffs < 0) { throw new Exception("section name offset overflow"); } entry.dataoffs = rd.ReadInt32(); if (entry.dataoffs < Size) { throw new Exception("section data offset overflow"); } entry.Size = rd.ReadInt32(); if (entry.Size < 0) { throw new Exception("section size overflow"); } entry.Name = header.string_at(entry.nameoffs); // Remember that there's a .dbg.natives section in the file. if (entry.Name == ".dbg.natives") { foundDbgNativesSection = true; } header.Sections[i] = entry; } // There was a brief period of incompatibility, where version == 0x0101 // and the packing changed, at the same time .dbg.natives was introduced. // Once the incompatibility was noted, version was bumped to 0x0102. header.debugUnpacked = (header.Version == SP1_VERSION_1_0) && !foundDbgNativesSection; return(header); }
public SmxFile(BinaryReader br) { Header = FileHeader.From(br); // Parse precursor sections. foreach (var section in Header.Sections) { if (section.Name == ".names") { Names = new SmxNameTable(Header, section); } else if (section.Name == ".dbg.strings") { DebugNames = new SmxNameTable(Header, section); } else if (section.Name == ".dbg.info") { DebugInfo = new SmxDebugInfoSection(Header, section); } } CalledFunctions = new SmxCalledFunctionsTable(); // .dbg.names was removed when RTTI was added. if (DebugNames == null) { DebugNames = Names; } // Parse out other sections. var unknown = new List <SectionEntry>(); foreach (var section in Header.Sections) { try { switch (section.Name) { case ".names": case ".dbg.strings": case ".dbg.info": break; case ".natives": Natives = new SmxNativeTable(Header, section, Names); break; case ".publics": Publics = new SmxPublicTable(Header, section, Names); break; case ".pubvars": Pubvars = new SmxPubvarTable(Header, section, Names); break; case ".tags": Tags = new SmxTagTable(Header, section, Names); break; case ".data": Data = new SmxDataSection(Header, section); break; case ".code": CodeV1 = new SmxCodeV1Section(Header, section); break; case ".dbg.files": DebugFiles = new SmxDebugFilesTable(Header, section, DebugNames); break; case ".dbg.lines": DebugLines = new SmxDebugLinesTable(Header, section); break; case ".dbg.natives": DebugNatives = new SmxDebugNativesTable(Header, section, DebugNames); break; case ".dbg.symbols": DebugSymbols = new SmxDebugSymbolsTable(Header, section, DebugInfo, DebugNames); break; case ".dbg.methods": DebugMethods = new SmxDebugMethods(Header, section, Names); break; case ".dbg.globals": DebugGlobals = new SmxDebugGlobals(Header, section, Names); break; case ".dbg.locals": DebugLocals = new SmxDebugLocals(this, Header, section, Names); break; case "rtti.data": RttiData = new SmxRttiData(this, Header, section); break; case "rtti.classdefs": RttiClassDefs = new SmxRttiClassDefTable(Header, section, Names); break; case "rtti.enumstructs": RttiEnumStructs = new SmxRttiEnumStructTable(Header, section, Names); break; case "rtti.enumstruct_fields": RttiEnumStructFields = new SmxRttiEnumStructFieldTable(Header, section, Names); break; case "rtti.fields": RttiFields = new SmxRttiFieldTable(Header, section, Names); break; case "rtti.methods": RttiMethods = new SmxRttiMethodTable(Header, section, Names); break; case "rtti.natives": RttiNatives = new SmxRttiNativeTable(Header, section, Names); break; case "rtti.enums": RttiEnums = new SmxRttiEnumTable(Header, section, Names); break; case "rtti.typedefs": RttiTypedefs = new SmxRttiTypedefTable(Header, section, Names); break; case "rtti.typesets": RttiTypesets = new SmxRttiTypesetTable(Header, section, Names); break; default: unknown.Add(section); break; } } catch { // Set a breakpoint here to see why the section failed to be parsed. unknown.Add(section); } } UnknownSections = unknown.ToArray(); // Disassemble all functions right away to find all called functions. if (DebugSymbols != null) { foreach (var entry in DebugSymbols.Entries) { if (entry.Ident != SymKind.Function) { continue; } V1Disassembler.TryDisassemble(this, CodeV1, entry.Address); } } if (Publics != null) { foreach (var pubfun in Publics.Entries) { V1Disassembler.TryDisassemble(this, CodeV1, (int)pubfun.Address); } } if (CalledFunctions != null) { foreach (var fun in CalledFunctions.Entries) { V1Disassembler.TryDisassemble(this, CodeV1, (int)fun.Address); } } }
public SmxDebugNativesTable(FileHeader file, SectionEntry header, SmxNameTable names) : base(file, header) { entries_ = DebugNativesHeader.From(file.SectionReader(header), names); }
public static DebugSymbolEntry[] From(FileHeader hdr, BinaryReader rd, SmxDebugInfoSection info, SmxNameTable names) { var entries = new DebugSymbolEntry[info.NumSymbols]; for (var i = 0; i < info.NumSymbols; i++) { var entry = new DebugSymbolEntry(); entry.Address = rd.ReadInt32(); entry.TagId = rd.ReadUInt16(); // There's a padding of 2 bytes after this short. if (hdr.debugUnpacked) rd.ReadBytes(2); entry.CodeStart = rd.ReadUInt32(); entry.CodeEnd = rd.ReadUInt32(); entry.Ident = (SymKind)rd.ReadByte(); entry.Scope = (SymScope)rd.ReadByte(); entry.dimcount = rd.ReadUInt16(); entry.nameoffs = rd.ReadInt32(); entry.Name = names.StringAt(entry.nameoffs); if (entry.dimcount > 0) entry.Dims = DebugSymbolDimEntry.From(hdr, rd, entry.dimcount); entries[i] = entry; } return entries; }
public SmxCodeV1Section(FileHeader file, SectionEntry header) : base(file, header) { ch_ = CodeV1Header.From(file.SectionReader(header)); }
public SmxTagTable(FileHeader file, SectionEntry header, SmxNameTable names) : base(file, header) { var tags = TagEntry.From(file.SectionReader(header), header, names); tags_ = new Tag[tags.Length]; for (var i = 0; i < tags.Length; i++) tags_[i] = new Tag(tags[i]); }
public SmxNameTable(FileHeader header, SectionEntry section) : base(header, section) { names_ = new Dictionary <int, string>(); }
public SmxNameTable(FileHeader header, SectionEntry section) : base(header, section) { names_ = new Dictionary<int, string>(); }
public SmxDebugGlobals(FileHeader file, SectionEntry header, SmxNameTable names) : base(file, header, names) { }
public SmxDebugLocals(SmxFile smx_file, FileHeader file, SectionEntry header, SmxNameTable names) : base(file, header, names) { smx_file_ = smx_file; }
public SmxFile(BinaryReader br) { Header = FileHeader.From(br); // Parse precursor sections. foreach (var section in Header.Sections) { if (section.Name == ".names") Names = new SmxNameTable(Header, section); else if (section.Name == ".dbg.strings") DebugNames = new SmxNameTable(Header, section); else if (section.Name == ".dbg.info") DebugInfo = new SmxDebugInfoSection(Header, section); } // Parse out other sections. var unknown = new List<SectionEntry>(); foreach (var section in Header.Sections) { switch (section.Name) { case ".names": case ".dbg.strings": case ".dbg.info": break; case ".natives": Natives = new SmxNativeTable(Header, section, Names); break; case ".publics": Publics = new SmxPublicTable(Header, section, Names); break; case ".pubvars": Pubvars = new SmxPubvarTable(Header, section, Names); break; case ".tags": Tags = new SmxTagTable(Header, section, Names); break; case ".data": Data = new SmxDataSection(Header, section); break; case ".code": CodeV1 = new SmxCodeV1Section(Header, section); break; case ".dbg.files": DebugFiles = new SmxDebugFilesTable(Header, section, DebugNames); break; case ".dbg.lines": DebugLines = new SmxDebugLinesTable(Header, section); break; case ".dbg.natives": DebugNatives = new SmxDebugNativesTable(Header, section, DebugNames); break; case ".dbg.symbols": DebugSymbols = new SmxDebugSymbolsTable(Header, section, DebugInfo, DebugNames); break; default: unknown.Add(section); break; } } UnknownSections = unknown.ToArray(); }