Esempio n. 1
0
 public Argument(VariableType type, string name, int tag_id, Tag tag, Dimension[] dims)
 {
     type_ = type;
     name_ = name;
     tag_id_ = tag_id;
     tag_ = tag;
     dims_ = dims;
 }
Esempio n. 2
0
 public Variable(int addr, int tag_id, Tag tag, uint codeStart,
                 uint codeEnd, VariableType type, Scope scope,
                 string name, Dimension[] dims = null)
 {
     addr_ = addr;
     tag_id_ = (uint)tag_id;
     tag_ = tag;
     codeStart_ = codeStart;
     codeEnd_ = codeEnd;
     type_ = type;
     scope_ = scope;
     name_ = name;
     dims_ = dims;
 }
Esempio n. 3
0
        public SourcePawnFile(byte[] binary)
        {
            BinaryReader reader = new BinaryReader(new MemoryStream(binary));
            header_.magic = reader.ReadUInt32();
            if (header_.magic != MAGIC)
                throw new Exception("bad magic - not SourcePawn file");
            header_.version = reader.ReadUInt16();
            header_.compression = (Compression)reader.ReadByte();
            header_.disksize = (int)reader.ReadUInt32();
            header_.imagesize = (int)reader.ReadUInt32();
            header_.sections = (int)reader.ReadByte();
            header_.stringtab = (int)reader.ReadUInt32();
            header_.dataoffs = (int)reader.ReadUInt32();

            sections_ = new Dictionary<string, Section>();

            // There was a brief period of incompatibility, where version == 0x0101
            // and the packing changed, at the same time .dbg.ntvarg was introduced.
            // Once the incompatibility was noted, version was bumped to 0x0102.
            debugUnpacked_ = (header_.version == 0x0101) && !sections_.ContainsKey(".dbg.natives");

            switch (header_.compression)
            {
                case Compression.Gzip:
                {
                    byte[] bits = new byte[header_.imagesize];
                    for (int i = 0; i < header_.dataoffs; i++)
                        bits[i] = binary[i];

                    int uncompressedSize = header_.imagesize - header_.dataoffs;
                    int compressedSize = header_.disksize - header_.dataoffs;
                    MemoryStream ms = new MemoryStream(binary, header_.dataoffs + 2, compressedSize - 2);
                    DeflateStream gzip = new DeflateStream(ms, CompressionMode.Decompress);

					int actualSize = gzip.Read(bits, header_.dataoffs, uncompressedSize);
					//Debug.Assert(actualSize == uncompressedSize, "uncompressed size mismatch, bad file?");

                    binary = bits;
                    break;
                }
            }

            // Read sections.
            for (int i = 0; i < header_.sections; i++)
            {
                int nameOffset = (int)reader.ReadUInt32();
                int dataoffs = (int)reader.ReadUInt32();
                int size = (int)reader.ReadUInt32();
                string name = ReadString(binary, header_.stringtab + nameOffset, header_.dataoffs);
                sections_[name] = new Section(dataoffs, size);
            }

            if (sections_.ContainsKey(".code"))
            {
                Section sc = sections_[".code"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                uint codesize = br.ReadUInt32();
                byte cellsize = br.ReadByte();
                byte codeversion = br.ReadByte();
                ushort flags = br.ReadUInt16();
                uint main = br.ReadUInt32();
                uint codeoffs = br.ReadUInt32();
                byte[] codeBytes = Slice(binary, sc.dataoffs + (int)codeoffs, (int)codesize);
                code_ = new Code(codeBytes, (int)flags, (int)codeversion);
            }

            if (sections_.ContainsKey(".data"))
            {
                Section sc = sections_[".data"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                uint datasize = br.ReadUInt32();
                uint memsize = br.ReadUInt32();
                uint dataoffs = br.ReadUInt32();
                byte[] dataBytes = Slice(binary, sc.dataoffs + (int)dataoffs, (int)datasize);
                data_ = new Data(dataBytes, (int)memsize);
            }

            if (sections_.ContainsKey(".publics"))
            {
                Section sc = sections_[".publics"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                int numPublics = sc.size / 8;
                publics_ = new Public[numPublics];
                for (int i = 0; i < numPublics; i++)
                {
                    uint address = br.ReadUInt32();
                    uint nameOffset = br.ReadUInt32();
                    string name = ReadString(binary, sections_[".names"].dataoffs + (int)nameOffset, header_.dataoffs);
                    publics_[i] = new Public(name, address);
                }
            }

            if (sections_.ContainsKey(".pubvars"))
            {
                Section sc = sections_[".pubvars"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                int numPubVars = sc.size / 8;
                pubvars_ = new PubVar[numPubVars];
                for (int i = 0; i < numPubVars; i++)
                {
                    uint address = br.ReadUInt32();
                    uint nameOffset = br.ReadUInt32();
                    string name = ReadString(binary, sections_[".names"].dataoffs + (int)nameOffset, header_.dataoffs);
                    pubvars_[i] = new PubVar(name, address);
                }
            }

            if (sections_.ContainsKey(".natives"))
            {
                Section sc = sections_[".natives"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                int numNatives = sc.size / 4;
                natives_ = new Native[numNatives];
                for (int i = 0; i < numNatives; i++)
                {
                    uint nameOffset = br.ReadUInt32();
                    string name = ReadString(binary, sections_[".names"].dataoffs + (int)nameOffset, header_.dataoffs);
                    natives_[i] = new Native(name, i);
                }
            }

            if (sections_.ContainsKey(".tags"))
            {
                Section sc = sections_[".tags"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                int numTags = sc.size / 8;
                tags_ = new Tag[numTags];
                for (int i = 0; i < numTags; i++)
                {
                    uint tag_id = br.ReadUInt32();
                    uint nameOffset = br.ReadUInt32();
                    string name = ReadString(binary, sections_[".names"].dataoffs + (int)nameOffset, header_.dataoffs);
                    tags_[i] = new Tag(name, tag_id);
                }
            }

            if (sections_.ContainsKey(".dbg.info"))
            {
                Section sc = sections_[".dbg.info"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                debugHeader_.numFiles = (int)br.ReadUInt32();
                debugHeader_.numLines = (int)br.ReadUInt32();
                debugHeader_.numSyms = (int)br.ReadUInt32();
            }

            if (sections_.ContainsKey(".dbg.files") && debugHeader_.numFiles > 0)
            {
                Section sc = sections_[".dbg.files"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                debugFiles_ = new DebugFile[debugHeader_.numFiles];
                for (int i = 0; i < debugHeader_.numFiles; i++)
                {
                    uint address = br.ReadUInt32();
                    uint nameOffset = br.ReadUInt32();
                    string name = ReadString(binary, sections_[".dbg.strings"].dataoffs + (int)nameOffset, header_.dataoffs);
                    debugFiles_[i] = new DebugFile(name, nameOffset);
                }
            }

            if (sections_.ContainsKey(".dbg.lines") && debugHeader_.numLines > 0)
            {
                Section sc = sections_[".dbg.lines"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                debugLines_ = new DebugLine[debugHeader_.numLines];
                for (int i = 0; i < debugHeader_.numLines; i++)
                {
                    uint address = br.ReadUInt32();
                    uint line = br.ReadUInt32();
                    debugLines_[i] = new DebugLine((int)line, address);
                }
            }

            if (sections_.ContainsKey(".dbg.symbols") && debugHeader_.numSyms > 0)
            {
                Section sc = sections_[".dbg.symbols"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                List<Variable> locals = new List<Variable>();
                List<Variable> globals = new List<Variable>();
                List<Function> functions = new List<Function>();
                for (int i = 0; i < debugHeader_.numSyms; i++)
                {
                    int addr = br.ReadInt32();
                    short tagid = br.ReadInt16();
                    uint codestart = br.ReadUInt32();
                    uint codeend = br.ReadUInt32();
                    byte ident = br.ReadByte();
                    Scope vclass = (Scope)br.ReadByte();
                    ushort dimcount = br.ReadUInt16();
                    uint nameOffset = br.ReadUInt32();
                    string name = ReadString(binary, sections_[".dbg.strings"].dataoffs + (int)nameOffset, header_.dataoffs);

                    if (ident == IDENT_FUNCTION)
                    {
                        Tag tag = tagid >= tags_.Length ? null : tags_[tagid];
                        Function func = new Function((uint)addr, codestart, codeend, name, tag);
                        functions.Add(func);
                    }
                    else
                    {
                        VariableType type = FromIdent(ident);
                        Dimension[] dims = null;
                        if (dimcount > 0)
                        {
                            dims = new Dimension[dimcount];
                            for (int dim = 0; dim < dimcount; dim++)
                            {
                                short dim_tagid = br.ReadInt16();
                                Tag dim_tag = dim_tagid >= tags_.Length ? null : tags_[dim_tagid];
                                uint size = br.ReadUInt32();
                                dims[dim] = new Dimension(dim_tagid, dim_tag, (int)size);
                            }
                        }

                        Tag tag = tagid >= tags_.Length ? null : tags_[tagid];
                        Variable var = new Variable(addr, tagid, tag, codestart, codeend, type, vclass, name, dims);
                        if (vclass == Scope.Global)
                            globals.Add(var);
                        else
                            locals.Add(var);
                    }
                }

                globals.Sort(delegate(Variable var1, Variable var2)
                {
                    return var1.address - var2.address;
                });
                functions.Sort(delegate(Function fun1, Function fun2)
                {
                    return (int)(fun1.address - fun2.address);
                });

                variables_ = locals.ToArray();
                globals_ = globals.ToArray();
                functions_ = functions.ToArray();
            }

            if (sections_.ContainsKey(".dbg.natives"))
            {
                Section sc = sections_[".dbg.natives"];
                BinaryReader br = new BinaryReader(new MemoryStream(binary, sc.dataoffs, sc.size));
                uint nentries = br.ReadUInt32();
                for (int i = 0; i < (int)nentries; i++)
                {
                    uint index = br.ReadUInt32();
                    uint nameOffset = br.ReadUInt32();
                    string name = ReadString(binary, sections_[".dbg.strings"].dataoffs + (int)nameOffset, header_.dataoffs);
                    short tagid = br.ReadInt16();
                    Tag tag = tagid >= tags_.Length ? null : tags_[tagid];
                    ushort nargs = br.ReadUInt16();

                    Argument[] args = new Argument[nargs];
                    for (ushort arg = 0; arg < nargs; arg++)
                    {
                        byte ident = br.ReadByte();
                        short arg_tagid = br.ReadInt16();
                        ushort dimcount = br.ReadUInt16();
                        uint argNameOffset = br.ReadUInt32();
                        string argName = ReadString(binary, sections_[".dbg.strings"].dataoffs + (int)argNameOffset, header_.dataoffs);
                        Tag argTag = arg_tagid >= tags_.Length ? null : tags_[arg_tagid];
                        VariableType type = FromIdent(ident);

                        Dimension[] dims = null;
                        if (dimcount > 0)
                        {
                            dims = new Dimension[dimcount];
                            for (int dim = 0; dim < dimcount; dim++)
                            {
                                short dim_tagid = br.ReadInt16();
                                Tag dim_tag = dim_tagid >= tags_.Length ? null : tags_[dim_tagid];
                                uint size = br.ReadUInt32();
                                dims[dim] = new Dimension(dim_tagid, dim_tag, (int)size);
                            }
                        }

                        args[arg] = new Argument(type, argName, arg_tagid, argTag, dims);
                    }

                    if ((int)index >+ natives_.Length)
                        continue;

                    natives_[index].setDebugInfo(tagid, tag, args);
                }
            }

            // For every function, attempt to build argument information.
            for (int i = 0; i < functions_.Length; i++)
            {
                Function fun = functions_[i];
                int argOffset = 12;
                var args = new List<Argument>();
                do
                {
                    Variable var = lookupVariable(fun.address, argOffset);
                    if (var == null)
                        break;
                    Argument arg = new Argument(var.type, var.name, (int)var.tag.tag_id, var.tag, var.dims);
                    args.Add(arg);
                    argOffset += 4;
                } while (true);
                fun.setArguments(args);
            }
        }