Ejemplo n.º 1
0
        private Section?LoadExportSection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint count))
            {
                return(null);
            }
            var exports = new List <ExportEntry>();

            for (int i = 0; i < count; ++i)
            {
                if (!rdr.TryReadVarUInt32(out uint len))
                {
                    return(null);
                }
                var field = Encoding.UTF8.GetString(rdr.ReadBytes(len));
                if (!rdr.TryReadByte(out byte kind))
                {
                    return(null);
                }
                if (!rdr.TryReadVarUInt32(out uint index))
                {
                    return(null);
                }
                exports.Add(new ExportEntry
                {
                    Field = field,
                    Kind  = kind,
                    Index = index,
                });
            }
            return(new ExportSection
            {
                ExportEntries = exports
            });
        }
Ejemplo n.º 2
0
 public WasmDisassembler(EndianImageReader rdr)
 {
     this.rdr = new WasmImageReader(new MemoryArea(rdr.Address, rdr.Bytes))
     {
         Offset = rdr.Offset
     };
 }
Ejemplo n.º 3
0
        private Section?LoadGlobalSection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint count))
            {
                return(null);
            }
            var globals = new List <GlobalEntry>();

            for (int i = 0; i < count; ++i)
            {
                var global_type = ReadGlobalType(rdr);
                if (global_type == null)
                {
                    return(null);
                }
                var expr = LoadInitExpr(rdr);
                globals.Add(new GlobalEntry
                {
                    Type     = global_type.Value,
                    InitExpr = expr,
                });
            }
            return(new GlobalSection
            {
                Globals = globals
            });
        }
Ejemplo n.º 4
0
        private DataType?ReadValueType(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarInt7(out sbyte ty))
            {
                return(null);
            }
            switch (ty)
            {
            case -0x01: return(PrimitiveType.Word32);                                          // i32

            case -0x02: return(PrimitiveType.Word64);                                          // i64

            case -0x03: return(PrimitiveType.Real32);                                          // f32

            case -0x04: return(PrimitiveType.Real64);                                          // f64

            case -0x10: return(new TypeReference("anyfunc", new StructureType("anyfunc", 4))); // anyfunc

            case -0x20: throw new NotImplementedException();                                   // func

            case -0x40: throw new NotImplementedException();                                   // pseudo type for representing an empty block_type

            default: throw new NotImplementedException();
            }
        }
Ejemplo n.º 5
0
 public WasmDisassembler(WasmArchitecture arch, EndianImageReader rdr)
 {
     this.arch = arch;
     this.addr = rdr.Address;
     this.rdr  = new WasmImageReader(new MemoryArea(rdr.Address, rdr.Bytes))
     {
         Offset = rdr.Offset
     };
 }
Ejemplo n.º 6
0
        private (DataType, bool)? ReadGlobalType(WasmImageReader rdr)
        {
            var dt = this.ReadValueType(rdr);

            if (!rdr.TryReadByte(out byte b))
            {
                return(null);
            }
            return(dt !, b != 0);
        }
Ejemplo n.º 7
0
        private FunctionType?LoadFuncType(WasmImageReader rdr)
        {
            byte       form;         // varint7     the value for the func type constructor as defined above
            uint       param_count;  // varuint32   the number of parameters to the function
            byte       return_count; // varuint1    the number of results from the function
            Identifier?ret = null;   // value_type ? the result type of the function(if return_count is 1)

            if (!rdr.TryReadVarUInt7(out form))
            {
                return(null);
            }
            if (!rdr.TryReadVarUInt32(out param_count))
            {
                return(null);
            }
            var args     = new List <Identifier>();
            int cbOffset = 0;

            for (int i = 0; i < param_count; ++i)
            {
                var dt = ReadValueType(rdr);
                if (dt == null)
                {
                    return(null);
                }
                args.Add(new Identifier(
                             "arg" + i,
                             dt,
                             new StackArgumentStorage(cbOffset, dt)));
                cbOffset += dt.Size;
            }
            if (!rdr.TryReadVarUInt7(out return_count))
            {
                return(null);
            }
            if (return_count == 1)
            {
                var dt = ReadValueType(rdr);
                if (dt is null)
                {
                    return(null);
                }
                ret = new Identifier(
                    "",
                    dt,
                    new StackArgumentStorage(0, dt));
            }
            return(new FunctionType(
                       ret !,
                       args.ToArray()));
        }
Ejemplo n.º 8
0
        public WasmImageReader LoadHeader()
        {
            var rdr = new WasmImageReader(RawImage);

            if (!rdr.TryReadLeUInt32(out uint magic))
            {
                throw new BadImageFormatException();
            }
            if (!rdr.TryReadLeUInt32(out uint version))
            {
                throw new BadImageFormatException();
            }
            return(rdr);
        }
Ejemplo n.º 9
0
        private List <Section> LoadSections(WasmImageReader rdr)
        {
            var sections = new List <Section>();

            for (;;)
            {
                var s = LoadSection(rdr);
                if (s == null)
                {
                    break;
                }
                sections.Add(s);
            }
            return(sections);
        }
Ejemplo n.º 10
0
        private Section?LoadDataSection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint count))
            {
                return(null);
            }
            var segments = new List <DataSegment>();

            for (int i = 0; i < count; ++i)
            {
                /*
                 * index    varuint32   the linear memory index (0 in the MVP)
                 * offset   init_expr   an i32 initializer expression that computes the offset at which to place the data
                 * size     varuint32   size of data (in bytes)
                 * data     bytes   sequence of size bytes
                 */
                if (!rdr.TryReadVarUInt32(out uint index))
                {
                    return(null);
                }
                var offset = LoadInitExpr(rdr);
                if (!rdr.TryReadVarUInt32(out uint size))
                {
                    return(null);
                }
                var bytes = rdr.ReadBytes(size);
                if (bytes == null)
                {
                    return(null);
                }
                segments.Add(new DataSegment
                {
                    MemoryIndex = index,
                    Offset      = offset,
                    Bytes       = bytes,
                });
            }
            return(new DataSection
            {
                Segments = segments
            });
        }
Ejemplo n.º 11
0
        private FunctionDefinition?LoadFunctionDefinition(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint len))
            {
                return(null);
            }
            var start = (int)rdr.Offset;
            var end   = start + (int)len;

            if (!rdr.TryReadVarUInt32(out uint cEntries))
            {
                return(null);
            }
            var locals = new List <LocalVariable>();

            for (int i = 0; i < cEntries; ++i)
            {
                if (!rdr.TryReadVarUInt32(out uint n))
                {
                    return(null);
                }
                var dt = ReadValueType(rdr);
                if (dt == null)
                {
                    return(null);
                }
                locals.AddRange(Enumerable.Range(0, (int)n).Select(nn => new LocalVariable {
                    DataType = dt
                }));
            }
            len -= (uint)(rdr.Offset - start);
            var codeBytes = rdr.ReadBytes(len);

            return(new FunctionDefinition
            {
                Start = start,
                End = end,
                Locals = locals.ToArray(),
                ByteCode = codeBytes
            });
        }
Ejemplo n.º 12
0
        private Section?LoadFunctionSection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint count))
            {
                return(null);
            }
            var decls = new List <uint>();

            for (int i = 0; i < count; ++i)
            {
                if (!rdr.TryReadVarUInt32(out uint decl))
                {
                    return(null);
                }
                decls.Add(decl);
            }
            return(new FunctionSection
            {
                Declarations = decls
            });
        }
Ejemplo n.º 13
0
        private (uint, uint)? ReadResizableLimits(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint flags))
            {
                return(null);
            }
            if (!rdr.TryReadVarUInt32(out uint init))
            {
                return(null);
            }
            uint max = 0;

            if ((flags & 1) != 0)
            {
                if (!rdr.TryReadVarUInt32(out max))
                {
                    return(null);
                }
            }
            return(init, max);
        }
Ejemplo n.º 14
0
        private Section?LoadElementSection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint count))
            {
                return(null);
            }
            var elementSegs = new List <ElementSegment>();

            for (int i = 0; i < count; ++i)
            {
                if (!rdr.TryReadVarUInt32(out uint table_index))
                {
                    return(null);
                }
                var offset = LoadInitExpr(rdr);
                if (!rdr.TryReadVarUInt32(out uint cElems))
                {
                    return(null);
                }
                var elements = new List <uint>();
                for (int j = 0; j < cElems; ++j)
                {
                    if (!rdr.TryReadVarUInt32(out uint elem))
                    {
                        return(null);
                    }
                    elements.Add(elem);
                }
                elementSegs.Add(new ElementSegment
                {
                    TableIndex = table_index,
                    Offset     = offset,
                    Elements   = elements,
                });
            }
            return(new ElementSection
            {
                Segments = elementSegs
            });
        }
Ejemplo n.º 15
0
        private Section?LoadCodeSection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint count))
            {
                return(null);
            }
            var funcBodies = new List <FunctionDefinition>();

            for (int i = 0; i < count; ++i)
            {
                var fd = LoadFunctionDefinition(rdr);
                if (fd == null)
                {
                    return(null);
                }
                funcBodies.Add(fd);
            }
            return(new CodeSection
            {
                Functions = funcBodies,
            });
        }
Ejemplo n.º 16
0
        private Section?LoadMemorySection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint count))
            {
                return(null);
            }
            var mems = new List <Memory>();

            for (int i = 0; i < count; ++i)
            {
                if (!rdr.TryReadVarUInt32(out uint flags))
                {
                    return(null);
                }
                if (!rdr.TryReadVarUInt32(out uint init))
                {
                    return(null);
                }
                uint max = 0;
                if ((flags & 1) != 0)
                {
                    if (!rdr.TryReadVarUInt32(out max))
                    {
                        return(null);
                    }
                }
                var mem = new Memory
                {
                    Flags   = flags,
                    Initial = init,
                    Maximum = max,
                };
                mems.Add(mem);
            }
            return(new MemorySection
            {
                Memories = mems,
            });
        }
Ejemplo n.º 17
0
        private Section?LoadTableSection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint count))
            {
                return(null);
            }
            var tables = new List <TableType>();

            for (int i = 0; i < count; ++i)
            {
                TableType?tt = ReadTableType(rdr);
                if (tt == null)
                {
                    return(null);
                }
                tables.Add(tt);
            }
            return(new TableSection
            {
                Tables = tables
            });
        }
Ejemplo n.º 18
0
        // The type section declares all function signatures that will be used in the module.
        private Section?LoadTypeSection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint count))
            {
                return(null);
            }

            var types = new List <FunctionType>();

            for (int i = 0; i < count; ++i)
            {
                var ft = LoadFuncType(rdr);
                if (ft is null)
                {
                    return(null);
                }
                types.Add(ft);
            }
            return(new TypeSection
            {
                Types = types,
            });
        }
Ejemplo n.º 19
0
        private TableType?ReadTableType(WasmImageReader rdr)
        {
            var dt = ReadValueType(rdr);

            if (dt == null)
            {
                return(null);
            }

            var tpl = ReadResizableLimits(rdr);

            if (tpl == null)
            {
                return(null);
            }

            return(new TableType
            {
                EntryType = dt,
                Initial = tpl.Value.Item1,
                Maximum = tpl.Value.Item2,
            });
        }
Ejemplo n.º 20
0
        public Section?LoadSection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt7(out byte bType))
            {
                return(null);            // no more data, return.
            }
            var type = (WasmSection)bType;

            if (!rdr.TryReadVarUInt32(out uint payload_len))
            {
                throw new BadImageFormatException();
            }
            string name;

            if (type == WasmSection.Custom)
            {
                var offset = rdr.Offset;
                // Custom sections' names are part of the payload.
                if (!rdr.TryReadVarUInt32(out uint name_len) || name_len == 0)
                {
                    throw new NotImplementedException();
                }
                name         = Encoding.UTF8.GetString(rdr.ReadBytes(name_len));
                payload_len -= (uint)(rdr.Offset - offset);
            }
            else
            {
                name = type.ToString();
            }

            byte[] bytes;
            if (payload_len > 0)
            {
                bytes = rdr.ReadBytes(payload_len);
            }
            else
            {
                bytes = new byte[0];
            }
            var rdr2 = new WasmImageReader(bytes);

            switch (type)
            {
            case WasmSection.Custom: return(LoadCustomSection(name, bytes)); // custom section

            case WasmSection.Type: return(LoadTypeSection(rdr2));            // Function signature declarations

            case WasmSection.Import: return(LoadImportSection(rdr2));        // Import declarations

            case WasmSection.Function: return(LoadFunctionSection(rdr2));    // Function declarations

            case WasmSection.Table: return(LoadTableSection(rdr2));          // Indirect function table and other tables

            case WasmSection.Memory: return(LoadMemorySection(rdr2));        // Memory attributes

            case WasmSection.Global: return(LoadGlobalSection(rdr2));        // Global declarations

            case WasmSection.Export: return(LoadExportSection(rdr2));        // Exports

            case WasmSection.Start: return(LoadStartSection(rdr2));          // Start function declaration

            case WasmSection.Element: return(LoadElementSection(rdr2));      // Elements section

            case WasmSection.Code: return(LoadCodeSection(rdr2));            // Function bodies (code)

            case WasmSection.Data: return(LoadDataSection(rdr2));            // Data segments

            default: throw new NotSupportedException();
            }
        }
Ejemplo n.º 21
0
        private uint LoadInitExpr(WasmImageReader rdr)
        {
            var eval = new WasmEvaluator(rdr);

            return(Convert.ToUInt32(eval.Run()));
        }
Ejemplo n.º 22
0
        private Section?LoadImportSection(WasmImageReader rdr)
        {
            if (!rdr.TryReadVarUInt32(out uint count))
            {
                return(null);
            }
            var imps = new List <Import>();

            for (uint i = 0; i < count; ++i)
            {
                if (!rdr.TryReadVarUInt32(out uint len))
                {
                    return(null);
                }
                string module = Encoding.UTF8.GetString(rdr.ReadBytes(len));
                if (!rdr.TryReadVarUInt32(out len))
                {
                    return(null);
                }
                string field = Encoding.UTF8.GetString(rdr.ReadBytes(len));
                if (!rdr.TryReadByte(out byte external_kind))
                {
                    return(null);
                }
                switch (external_kind)
                {
                case 0:
                    uint function_index;
                    if (!rdr.TryReadVarUInt32(out function_index))
                    {
                        return(null);
                    }
                    imps.Add(new Import
                    {
                        Type   = SymbolType.ExternalProcedure,
                        Module = module,
                        Field  = field,
                        Index  = function_index,
                    });
                    break;

                case 1:
                    var table = this.ReadTableType(rdr);
                    if (table == null)
                    {
                        return(null);
                    }
                    imps.Add(new Import
                    {
                        Type      = SymbolType.Table,
                        Module    = module,
                        Field     = field,
                        TableType = table,
                    });
                    break;

                case 2:
                    var memory_type = ReadResizableLimits(rdr);
                    if (memory_type == null)
                    {
                        return(null);
                    }
                    imps.Add(new Import
                    {
                        Type       = SymbolType.AddressSpace,
                        Module     = module,
                        Field      = field,
                        MemoryType = memory_type.Value,
                    });
                    break;

                case 3:
                    var global_type = ReadGlobalType(rdr);
                    if (global_type == null)
                    {
                        return(null);
                    }
                    imps.Add(new Import
                    {
                        Type       = SymbolType.Data,
                        Module     = module,
                        Field      = field,
                        GlobalType = global_type.Value,
                    });
                    break;

                default:
                    throw new NotImplementedException();
                }

                /*
                 *
                 * 0 indicating a Function import or definition
                 * 1 indicating a Table import or definition
                 * 2 indicating a Memory import or definition
                 * 3 indicating a Global import or definition
                 *
                 */
            }
            return(new ImportSection
            {
                Imports = imps,
            });
        }
Ejemplo n.º 23
0
 public WasmEvaluator(WasmImageReader rdr)
 {
     this.rdr   = rdr;
     this.stack = new Stack <object>();
 }
Ejemplo n.º 24
0
 private Section LoadStartSection(WasmImageReader rdr)
 {
     throw new NotImplementedException();
 }