예제 #1
0
        public SmxRttiData(SmxFile file, FileHeader file_header, SectionEntry header)
            : base(file_header, header)
        {
            smx_file_ = file;
            var reader = file_header.SectionReader(header);

            bytes_ = reader.ReadBytes(header.Size);
        }
예제 #2
0
        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]);
            }
        }
예제 #3
0
        public SmxDebugSymbols(FileHeader file, SectionEntry header, SmxNameTable names)
            : base(file, header, names)
        {
            var reader = file.SectionReader(header);

            base.init(reader);

            Entries = new DebugVarEntry[row_count_];
            for (uint i = 0; i < row_count_; i++)
            {
                Entries[i] = DebugVarEntry.From(reader, i);
            }
        }
예제 #4
0
        public SmxRttiTypesetTable(FileHeader file, SectionEntry header, SmxNameTable names)
            : base(file, header, names)
        {
            var reader = file.SectionReader(header);

            base.init(reader);

            Typesets = new RttiTypeset[row_count_];
            for (uint i = 0; i < row_count_; i++)
            {
                int index = reader.ReadInt32();
                Typesets[i].name      = names.StringAt(index);
                Typesets[i].signature = reader.ReadInt32();
            }
        }
예제 #5
0
        public SmxRttiEnumStructTable(FileHeader file, SectionEntry header, SmxNameTable names)
            : base(file, header, names)
        {
            var reader = file.SectionReader(header);

            base.init(reader);

            Entries = new RttiEnumStruct[row_count_];
            for (uint i = 0; i < row_count_; i++)
            {
                Entries[i]             = new RttiEnumStruct();
                Entries[i].name_offset = reader.ReadInt32();
                Entries[i].first_field = reader.ReadInt32();
                Entries[i].size        = reader.ReadInt32();
                Entries[i].name        = names.StringAt(Entries[i].name_offset);
            }
        }
예제 #6
0
        public SmxRttiFieldTable(FileHeader file, SectionEntry header, SmxNameTable names)
            : base(file, header, names)
        {
            var reader = file.SectionReader(header);

            base.init(reader);

            Fields = new RttiField[row_count_];
            for (uint i = 0; i < row_count_; i++)
            {
                Fields[i]             = new RttiField();
                Fields[i].flags       = reader.ReadInt16();
                Fields[i].name_offset = reader.ReadInt32();
                Fields[i].type_id     = reader.ReadInt32();
                Fields[i].name        = names.StringAt(Fields[i].name_offset);
            }
        }
예제 #7
0
        public SmxRttiMethodTable(FileHeader file, SectionEntry header, SmxNameTable names)
            : base(file, header, names)
        {
            var reader = file.SectionReader(header);

            base.init(reader);

            Methods = new RttiMethod[row_count_];
            for (uint i = 0; i < row_count_; i++)
            {
                int index = reader.ReadInt32();
                Methods[i].name        = names.StringAt(index);
                Methods[i].pcode_start = reader.ReadInt32();
                Methods[i].pcode_end   = reader.ReadInt32();
                Methods[i].signature   = reader.ReadInt32();
            }
        }
예제 #8
0
        public SmxRttiEnumTable(FileHeader file, SectionEntry header, SmxNameTable names)
            : base(file, header, names)
        {
            var reader = file.SectionReader(header);

            base.init(reader);

            Enums = new string[row_count_];
            for (uint i = 0; i < row_count_; i++)
            {
                int index = reader.ReadInt32();
                Enums[i] = names.StringAt(index);
                // reserved0-2.
                reader.ReadInt32();
                reader.ReadInt32();
                reader.ReadInt32();
            }
        }
예제 #9
0
        public static DebugLineEntry[] From(BinaryReader rd, SectionEntry header)
        {
            if (header.Size % Size != 0)
            {
                throw new Exception("invalid debug line table size");
            }
            var count   = header.Size / Size;
            var entries = new DebugLineEntry[count];

            for (var i = 0; i < count; i++)
            {
                var entry = new DebugLineEntry();
                entry.Address = rd.ReadUInt32();
                entry.Line    = rd.ReadUInt32();
                entries[i]    = entry;
            }
            return(entries);
        }
예제 #10
0
        public static NativeEntry[] From(BinaryReader rd, SectionEntry header, SmxNameTable names)
        {
            if (header.Size % Size != 0)
            {
                throw new Exception("invalid native table size");
            }
            var count   = header.Size / Size;
            var entries = new NativeEntry[count];

            for (var i = 0; i < count; i++)
            {
                var entry = new NativeEntry();
                entry.nameoffs = rd.ReadInt32();
                entry.Name     = names.StringAt(entry.nameoffs);
                entries[i]     = entry;
            }
            return(entries);
        }
예제 #11
0
        public SmxRttiClassDefTable(FileHeader file, SectionEntry header, SmxNameTable names)
            : base(file, header, names)
        {
            var reader = file.SectionReader(header);

            base.init(reader);

            Defs = new RttiClassDef[row_count_];
            for (uint i = 0; i < row_count_; i++)
            {
                Defs[i]             = new RttiClassDef();
                Defs[i].flags       = reader.ReadInt32();
                Defs[i].name_offset = reader.ReadInt32();
                Defs[i].first_field = reader.ReadInt32();
                Defs[i].name        = names.StringAt(Defs[i].name_offset);
                // reserved0-3
                reader.ReadInt32();
                reader.ReadInt32();
                reader.ReadInt32();
                reader.ReadInt32();
            }
        }
예제 #12
0
 public SmxDebugInfoSection(FileHeader file, SectionEntry header)
     : base(file, header)
 {
     info_ = DebugInfoHeader.From(file.SectionReader(header));
 }
예제 #13
0
 public SmxCodeV1Section(FileHeader file, SectionEntry header)
     : base(file, header)
 {
     ch_ = CodeV1Header.From(file.SectionReader(header));
 }
예제 #14
0
 private void renderSectionHeaderDetail(SectionEntry header)
 {
     startDetailUpdate();
     addDetailLine(".nameoffs = 0x{0:x} ; \"{1}\"", header.nameoffs, header.Name);
     addDetailLine(".dataoffs = 0x{0:x}", header.dataoffs);
     addDetailLine(".size = {0} bytes", header.Size);
 }
예제 #15
0
 public BinaryReader SectionReader(SectionEntry section)
 {
     var stream = new MemoryStream(Data, section.dataoffs, section.Size);
     return new BinaryReader(stream);
 }
예제 #16
0
 public SmxNativeTable(FileHeader file, SectionEntry header, SmxNameTable names)
     : base(file, header)
 {
     natives_ = NativeEntry.From(file.SectionReader(header), header, names);
 }
예제 #17
0
 public SmxNativeTable(FileHeader file, SectionEntry header, SmxNameTable names)
     : base(file, header)
 {
     natives_ = NativeEntry.From(file.SectionReader(header), header, names);
 }
예제 #18
0
 public SmxDebugNativesTable(FileHeader file, SectionEntry header, SmxNameTable names)
     : base(file, header)
 {
     entries_ = DebugNativesHeader.From(file.SectionReader(header), names);
 }
예제 #19
0
 public static PublicEntry[] From(BinaryReader rd, SectionEntry header, SmxNameTable names)
 {
     if (header.Size % Size != 0)
         throw new Exception("invalid public table size");
     var count = header.Size / Size;
     var entries = new PublicEntry[count];
     for (var i = 0; i < count; i++)
     {
         var entry = new PublicEntry();
         entry.Address = rd.ReadUInt32();
         entry.nameoffs = rd.ReadInt32();
         entry.Name = names.StringAt(entry.nameoffs);
         entries[i] = entry;
     }
     return entries;
 }
예제 #20
0
 public static DebugLineEntry[] From(BinaryReader rd, SectionEntry header)
 {
     if (header.Size % Size != 0)
         throw new Exception("invalid debug line table size");
     var count = header.Size / Size;
     var entries = new DebugLineEntry[count];
     for (var i = 0; i < count; i++)
     {
         var entry = new DebugLineEntry();
         entry.Address = rd.ReadUInt32();
         entry.Line = rd.ReadUInt32();
         entries[i] = entry;
     }
     return entries;
 }
예제 #21
0
        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;
        }
예제 #22
0
 public SmxDebugSymbolsTable(FileHeader file, SectionEntry header, SmxDebugInfoSection info, SmxNameTable names)
     : base(file, header)
 {
     entries_ = DebugSymbolEntry.From(file, file.SectionReader(header), info, names);
 }
예제 #23
0
 public SmxNameTable(FileHeader header, SectionEntry section)
     : base(header, section)
 {
     names_ = new Dictionary<int, string>();
 }
예제 #24
0
 public SmxCodeV1Section(FileHeader file, SectionEntry header)
     : base(file, header)
 {
     ch_ = CodeV1Header.From(file.SectionReader(header));
 }
예제 #25
0
 public SmxDebugLinesTable(FileHeader file, SectionEntry header)
     : base(file, header)
 {
     entries_ = DebugLineEntry.From(file.SectionReader(header), header);
 }
예제 #26
0
 public SmxNameTable(FileHeader header, SectionEntry section)
     : base(header, section)
 {
     names_ = new Dictionary <int, string>();
 }
예제 #27
0
 public SmxDebugSymbolsTable(FileHeader file, SectionEntry header, SmxDebugInfoSection info, SmxNameTable names)
     : base(file, header)
 {
     entries_ = DebugSymbolEntry.From(file, file.SectionReader(header), info, names);
 }
예제 #28
0
 public SmxDebugLinesTable(FileHeader file, SectionEntry header)
     : base(file, header)
 {
     entries_ = DebugLineEntry.From(file.SectionReader(header), header);
 }
예제 #29
0
 public SmxSection(FileHeader file, SectionEntry header)
 {
     file_   = file;
     header_ = header;
 }
예제 #30
0
 public SmxDebugGlobals(FileHeader file, SectionEntry header, SmxNameTable names)
     : base(file, header, names)
 {
 }
예제 #31
0
 public SmxPubvarTable(FileHeader file, SectionEntry header, SmxNameTable names)
     : base(file, header)
 {
     pubvars_ = PubvarEntry.From(file.SectionReader(header), header, names);
 }
예제 #32
0
        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);
        }
예제 #33
0
 public SmxDataSection(FileHeader file, SectionEntry header)
     : base(file, header)
 {
     dh_ = DataHeader.From(file.SectionReader(header));
 }
예제 #34
0
 public SmxRttiListTable(FileHeader file, SectionEntry header, SmxNameTable names)
     : base(file, header)
 {
     var reader = file.SectionReader(header);
 }
예제 #35
0
 public SmxDebugInfoSection(FileHeader file, SectionEntry header)
     : base(file, header)
 {
     info_ = DebugInfoHeader.From(file.SectionReader(header));
 }
예제 #36
0
 public SmxSection(FileHeader file, SectionEntry header)
 {
     file_ = file;
     header_ = header;
 }
예제 #37
0
 public SmxDebugFilesTable(FileHeader file, SectionEntry header, SmxNameTable names)
     : base(file, header)
 {
     entries_ = DebugFileEntry.From(file.SectionReader(header), header, names);
 }
예제 #38
0
 public SmxPubvarTable(FileHeader file, SectionEntry header, SmxNameTable names)
     : base(file, header)
 {
     pubvars_ = PubvarEntry.From(file.SectionReader(header), header, names);
 }
예제 #39
0
 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]);
 }
예제 #40
0
 public SmxDataSection(FileHeader file, SectionEntry header)
     : base(file, header)
 {
     dh_ = DataHeader.From(file.SectionReader(header));
 }
예제 #41
0
 public SmxDebugLocals(SmxFile smx_file, FileHeader file, SectionEntry header, SmxNameTable names)
     : base(file, header, names)
 {
     smx_file_ = smx_file;
 }
예제 #42
0
        public BinaryReader SectionReader(SectionEntry section)
        {
            var stream = new MemoryStream(Data, section.dataoffs, section.Size);

            return(new BinaryReader(stream));
        }