Skip to content

Commit

Permalink
Add interface method name recovery
Browse files Browse the repository at this point in the history
  • Loading branch information
stevemk14ebr committed Oct 9, 2023
1 parent 532f64c commit 60e1cf4
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ restartParseWithRealTextBase:
extractMetadata.Types = types
}

// the ITabLinks did not always exist, older versions it will be NULL
interfaces, err := file.ParseITabLinks(extractMetadata.Version, moduleData, extractMetadata.TabMeta.PointerSize == 8, extractMetadata.TabMeta.Endianess == "LittleEndian")
if err == nil {
extractMetadata.Interfaces = interfaces
Expand Down
31 changes: 31 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"os"
"strings"
"testing"

_ "net/http/pprof"
Expand Down Expand Up @@ -53,6 +54,36 @@ func TestAllVersions(t *testing.T) {
}
}

if v != "15" && v != "16" {
found_interface := false
for _, typ := range data.Types {
if typ.Str == "io.Writer" && typ.Kind == "Interface" {
found_interface = true
if !strings.Contains(typ.Reconstructed, "Write([]uint8) (int, error)") {
t.Errorf("Go %s interface method name recovery failed", v)
}
}
}

if !found_interface {
t.Errorf("Go %s interface recovery failed", v)
}
} else {
found_interface := false
for _, typ := range data.Types {
if typ.Str == "os.FileInfo" && typ.Kind == "Interface" {
found_interface = true
if !strings.Contains(typ.Reconstructed, "IsDir() bool") {
t.Errorf("Go %s interface method name recovery failed", v)
}
}
}

if !found_interface {
t.Errorf("Go %s interface recovery failed", v)
}
}

if len(data.StdFunctions) == 0 {
t.Errorf("Go %s std functions failed on %s: %s", v, file, err)
}
Expand Down
23 changes: 18 additions & 5 deletions objfile/objfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -1447,10 +1447,17 @@ func (e *Entry) ParseType_impl(runtimeVersion string, moduleData *ModuleData, ty

typeAddr := decodePtrSizeBytes(imethoddata[ptrSize*2:ptrSize*3], is64bit, littleendian)
parsedTypesIn, _ = e.ParseType_impl(runtimeVersion, moduleData, typeAddr, is64bit, littleendian, parsedTypesIn)

name_ptr := decodePtrSizeBytes(imethoddata[0:ptrSize], is64bit, littleendian)
name, err := e.readRTypeName(runtimeVersion, 0, name_ptr, is64bit, littleendian)
if err != nil {
continue
}

methodfunc, found := parsedTypesIn.Get(typeAddr)
if found {
interfaceDef += "\nmethod" + strconv.Itoa(i) + " " + methodfunc.(Type).Str
cinterfaceDef += methodfunc.(Type).CStr + "method" + strconv.Itoa(i) + ";\n"
interfaceDef += strings.Replace(methodfunc.(Type).Str, "func", name, 1) + "\n"
cinterfaceDef += methodfunc.(Type).CStr + " " + name + ";\n"
}
}
interfaceDef += "\n}"
Expand Down Expand Up @@ -1513,7 +1520,7 @@ func (e *Entry) ParseType_impl(runtimeVersion string, moduleData *ModuleData, ty
interfaceDef := "type interface {"
cinterfaceDef := "struct interface {\n"
(*_type).CStr = "interface_"
if *&_type.flags&tflagNamed != 0 {
if _type.flags&tflagNamed != 0 {
interfaceDef = fmt.Sprintf("type %s interface {", _type.Str)
cinterfaceDef = fmt.Sprintf("struct %s_interface {\n", _type.CStr)
(*_type).CStr = fmt.Sprintf("%s_interface", _type.CStr)
Expand All @@ -1539,10 +1546,16 @@ func (e *Entry) ParseType_impl(runtimeVersion string, moduleData *ModuleData, ty
typeAddr := moduleData.Types + uint64(method.Typ)
parsedTypesIn, _ = e.ParseType_impl(runtimeVersion, moduleData, typeAddr, is64bit, littleendian, parsedTypesIn)

name_ptr := moduleData.Types + uint64(method.Name)
name, err := e.readRTypeName(runtimeVersion, 0, name_ptr, is64bit, littleendian)
if err != nil {
continue
}

methodfunc, found := parsedTypesIn.Get(typeAddr)
if found {
interfaceDef += "\nmethod" + strconv.Itoa(i) + " " + methodfunc.(Type).Str
cinterfaceDef += methodfunc.(Type).CStr + " method" + strconv.Itoa(i) + ";\n"
interfaceDef += strings.Replace(methodfunc.(Type).Str, "func", name, 1) + "\n"
cinterfaceDef += methodfunc.(Type).CStr + " " + name + ";\n"
}
}
interfaceDef += "\n}"
Expand Down

0 comments on commit 60e1cf4

Please sign in to comment.