From df8fe278bd12d27d054e36819c486e8ab784c1f7 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Tue, 16 Oct 2018 15:12:32 +0200 Subject: [PATCH 1/3] Warn when modules are missing before attempting disassembly It won't work otherwise, and the error will be very confusing. --- disasm/disasm.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/disasm/disasm.go b/disasm/disasm.go index 743c19c9..dfea0bc8 100644 --- a/disasm/disasm.go +++ b/disasm/disasm.go @@ -9,6 +9,7 @@ import ( "bytes" "encoding/binary" "errors" + "fmt" "io" "math" @@ -97,6 +98,10 @@ func NewDisassembly(fn wasm.Function, module *wasm.Module) (*Disassembly, error) } disas := &Disassembly{} + if len(module.FunctionIndexSpace) != len(module.Import.Entries)+len(module.Function.Types) { + panic(fmt.Sprintf("Attempting to disassemble a module that is missing imports %d != %d + %d", len(module.FunctionIndexSpace), len(module.Import.Entries), len(module.Function.Types))) + } + // A stack of int arrays holding indices to instructions that make the stack // polymorphic. Each block has its corresponding array. We start with one // array for the root stack From 011ece437314ee9d8c49d728c675134442b4b372 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Thu, 18 Oct 2018 18:45:56 +0200 Subject: [PATCH 2/3] Simulate an imported module to allow disassembly of modules with imports. --- cmd/wasm-dump/main.go | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/cmd/wasm-dump/main.go b/cmd/wasm-dump/main.go index 19e90078..388a9a24 100644 --- a/cmd/wasm-dump/main.go +++ b/cmd/wasm-dump/main.go @@ -82,7 +82,42 @@ func process(w io.Writer, fname string) { } defer f.Close() - m, err := wasm.ReadModule(f, nil) + // Decode the module in order to fake its imports as exports + mod, err := wasm.DecodeModule(f) + if err != nil { + log.Fatalf("Could not read module: %v", err) + } + + resolver := func(name string) (*wasm.Module, error) { + m := wasm.NewModule() + m.Types = mod.Types + m.Export = &wasm.SectionExports{ + Entries: make(map[string]wasm.ExportEntry), + } + m.FunctionIndexSpace = []wasm.Function{} + for index, imp := range mod.Import.Entries { + fmt.Println(imp.ModuleName, imp.FieldName, imp.Type) + if imp.ModuleName == name { + m.Export.Entries[imp.FieldName] = wasm.ExportEntry{ + FieldStr: name, + Kind: imp.Type.Kind(), + Index: uint32(index), + } + if imp.Type.Kind() == wasm.ExternalFunction { + m.FunctionIndexSpace = append(m.FunctionIndexSpace, wasm.Function{ + Body: &wasm.FunctionBody{}, + }) + } + } + } + return m, nil + } + + // We already read the file without trying to resolve imports, + // start over in order to do that work now. + f.Seek(0, os.SEEK_SET) + + m, err := wasm.ReadModule(f, resolver) if err != nil { log.Fatalf("could not read module: %v", err) } From 375ee47bcc9e8a5e6e37e7c03c882593f5bada37 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Fri, 19 Oct 2018 11:50:09 +0200 Subject: [PATCH 3/3] Fix nil pointer error --- disasm/disasm.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/disasm/disasm.go b/disasm/disasm.go index dfea0bc8..8d148ed8 100644 --- a/disasm/disasm.go +++ b/disasm/disasm.go @@ -98,8 +98,12 @@ func NewDisassembly(fn wasm.Function, module *wasm.Module) (*Disassembly, error) } disas := &Disassembly{} - if len(module.FunctionIndexSpace) != len(module.Import.Entries)+len(module.Function.Types) { - panic(fmt.Sprintf("Attempting to disassemble a module that is missing imports %d != %d + %d", len(module.FunctionIndexSpace), len(module.Import.Entries), len(module.Function.Types))) + if module.Import != nil { + ninternal, _ := leb128.ReadVarint32(bytes.NewReader(module.Code.Bytes)) + nexternal := len(module.FunctionIndexSpace) - int(ninternal) + if nexternal != len(module.Import.Entries) { + panic(fmt.Sprintf("Attempting to disassemble a module that is missing imports %d != %d", nexternal, len(module.Import.Entries))) + } } // A stack of int arrays holding indices to instructions that make the stack