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; }
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; }
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); } }