Example #1
0
 public static TypeUnit FromVariable(Variable var)
 {
     switch (var.type)
     {
         case VariableType.Normal:
             return FromTag(var.tag);
         case VariableType.Array:
             return new TypeUnit(new PawnType(var.tag), var.dims.Length);
         case VariableType.Reference:
         {
             TypeUnit tu = new TypeUnit(new PawnType(var.tag));
             return new TypeUnit(tu);
         }
         case VariableType.ArrayReference:
         {
             TypeUnit tu = new TypeUnit(new PawnType(var.tag), var.dims.Length);
             return new TypeUnit(tu);
         }
     }
     return null;
 }
Example #2
0
        private void writeGlobal(Variable var)
        {
            string decl = var.scope == Scope.Global
                                       ? "" //"new"
                                       : "static";
            if (var.tag.name == "Plugin")
            {
                int nameOffset = file_.int32FromData(var.address + 0);
                int descriptionOffset = file_.int32FromData(var.address + 4);
                int authorOffset = file_.int32FromData(var.address + 8);
                int versionOffset = file_.int32FromData(var.address + 12);
                int urlOffset = file_.int32FromData(var.address + 16);
                string name = file_.stringFromData(nameOffset);
                string description = file_.stringFromData(descriptionOffset);
                string author = file_.stringFromData(authorOffset);
                string version = file_.stringFromData(versionOffset);
                string url = file_.stringFromData(urlOffset);

                outputLine("public Plugin myinfo =");
                outputLine("{");
                increaseIndent();
                outputLine("name = " + buildString(name) + ",");
                outputLine("description = " + buildString(description) + ",");
                outputLine("author = " + buildString(author) + ",");
                outputLine("version = " + buildString(version) + ",");
                outputLine("url = " + buildString(url));
                decreaseIndent();
                outputLine("};");
            }
            else if (var.tag.name == "String")
            {
                if (var.dims.Length == 1)
                {
                    string text = decl + " char " + var.name + "[" + var.dims[0].size + "]";
                    string primer = file_.stringFromData(var.address);
                    if (primer.Length > 0)
                        text += " = " + buildString(primer);
                    outputLine(text + ";");
                }
                else
                {
                    string text = decl + " " + buildTag(var.tag) + var.name;
                    if (var.dims != null)
                    {
                        for (int i = 0; i < var.dims.Length; i++)
                            text += "[" + var.dims[i].size + "]";
                    }
                    if (isArrayEmpty(var))
                    {
                        outputLine(text + ";");
                        return;
                    }
                    outputLine(text + " =");
                    outputLine("{");
                    increaseIndent();
                    dumpStringArray(var, var.address, 0);
                    decreaseIndent();
                    outputLine("}");
                }
            }
            else if (var.dims == null || var.dims.Length == 0)
            {
                string text = decl + " " + buildTag(var.tag) + var.name;
                int value = file_.int32FromData(var.address);
                if (value != 0)
                {
                    text += " = " + value;
                }
                outputLine(text + ";");
            }
            else if (isArrayEmpty(var))
            {
                string text = decl + " " + buildTag(var.tag) + var.name;
                if (var.dims != null)
                {
                    for (int i = 0; i < var.dims.Length; i++)
                        text += "[" + var.dims[i].size + "]";
                }
                outputLine(text + ";");
            }
            else
            {
                string text = decl + " " + buildTag(var.tag) + var.name;
                if (var.dims != null)
                {
                    for (int i = 0; i < var.dims.Length; i++)
                        text += "[" + var.dims[i].size + "]";
                }
                outputLine(text + " =");
                outputLine("{");
                increaseIndent();
                dumpArray(var, var.address, 0);
                decreaseIndent();
                outputLine("}");
            }
        }
Example #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);
            }
        }
Example #4
0
        private void dumpStringArray(Variable var, int address, int level)
        {
            if (level == var.dims.Length - 2)
            {
                dumpStringArray(address, var.dims[level].size);
                return;
            }

            Debug.Assert(false);

            for (int i = 0; i < var.dims[i].size; i++)
            {
                int abase = address + i * 4;
                int inner = file_.int32FromData(abase);
                int final = abase + inner;
                outputLine("{");
                increaseIndent();
                dumpStringArray(var, final, level + 1);
                decreaseIndent();
                if (i == var.dims[i].size - 1)
                    outputLine("}");
                else
                    outputLine("},");
            }
        }
Example #5
0
 private void dumpArray(Variable var, int address, int level)
 {
     if (level == var.dims.Length - 1)
     {
         dumpArray(address, var.dims[level].size);
         return;
     }
     int maxI = var.dims.Length;
     for (int i = 0; i < maxI; i++)
     {
         if (var.dims[i].size >= i)
         {
             break;
         }
         int abase = address + i * 4;
         int inner = file_.int32FromData(abase);
         int final = abase + inner;
         outputLine("{");
         increaseIndent();
         dumpArray(var, final, level + 1);
         decreaseIndent();
         if (i == var.dims[i].size - 1)
             outputLine("}");
         else
             outputLine("},");
     }
 }
Example #6
0
 private bool isArrayEmpty(Variable var)
 {
     var dims = new int[var.dims.Length];
     for (int i = 0; i < var.dims.Length; i++)
         dims[i] = var.dims[i].size;
     if (var.tag.name == "String")
         dims[dims.Length - 1] /= 4;
     return isArrayEmpty(var.address, dims, 0);
 }
Example #7
0
 private string buildVarDeclaration(Variable var)
 {
     string prefix = var.type == VariableType.Reference
                     ? "&"
                     : "";
     string decl = prefix + buildTag(var.tag) + var.name;
     if (var.dims != null)
     {
         for (int i = 0; i < var.dims.Length; i++)
         {
             Dimension dim = var.dims[i];
             decl += "[";
             if (dim.size >= 1)
             {
                 if (var.tag != null && var.tag.name == "String")
                     decl += dim.size * 4;
                 else
                     decl += dim.size;
             }
             decl += "]";
         }
     }
     return decl;
 }
Example #8
0
 public DGlobal(Variable var)
 {
     //Debug.Assert(var != null);
     var_ = var;
 }
Example #9
0
 public DDeclareStatic(Variable var)
 {
     var_ = var;
 }
Example #10
0
 public void setVariable(Variable var)
 {
     var_ = var;
 }