Skip to content

Commit 60e1cf4

Browse files
committed
Add interface method name recovery
1 parent 532f64c commit 60e1cf4

File tree

3 files changed

+50
-5
lines changed

3 files changed

+50
-5
lines changed

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ restartParseWithRealTextBase:
268268
extractMetadata.Types = types
269269
}
270270

271+
// the ITabLinks did not always exist, older versions it will be NULL
271272
interfaces, err := file.ParseITabLinks(extractMetadata.Version, moduleData, extractMetadata.TabMeta.PointerSize == 8, extractMetadata.TabMeta.Endianess == "LittleEndian")
272273
if err == nil {
273274
extractMetadata.Interfaces = interfaces

main_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"os"
8+
"strings"
89
"testing"
910

1011
_ "net/http/pprof"
@@ -53,6 +54,36 @@ func TestAllVersions(t *testing.T) {
5354
}
5455
}
5556

57+
if v != "15" && v != "16" {
58+
found_interface := false
59+
for _, typ := range data.Types {
60+
if typ.Str == "io.Writer" && typ.Kind == "Interface" {
61+
found_interface = true
62+
if !strings.Contains(typ.Reconstructed, "Write([]uint8) (int, error)") {
63+
t.Errorf("Go %s interface method name recovery failed", v)
64+
}
65+
}
66+
}
67+
68+
if !found_interface {
69+
t.Errorf("Go %s interface recovery failed", v)
70+
}
71+
} else {
72+
found_interface := false
73+
for _, typ := range data.Types {
74+
if typ.Str == "os.FileInfo" && typ.Kind == "Interface" {
75+
found_interface = true
76+
if !strings.Contains(typ.Reconstructed, "IsDir() bool") {
77+
t.Errorf("Go %s interface method name recovery failed", v)
78+
}
79+
}
80+
}
81+
82+
if !found_interface {
83+
t.Errorf("Go %s interface recovery failed", v)
84+
}
85+
}
86+
5687
if len(data.StdFunctions) == 0 {
5788
t.Errorf("Go %s std functions failed on %s: %s", v, file, err)
5889
}

objfile/objfile.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,10 +1447,17 @@ func (e *Entry) ParseType_impl(runtimeVersion string, moduleData *ModuleData, ty
14471447

14481448
typeAddr := decodePtrSizeBytes(imethoddata[ptrSize*2:ptrSize*3], is64bit, littleendian)
14491449
parsedTypesIn, _ = e.ParseType_impl(runtimeVersion, moduleData, typeAddr, is64bit, littleendian, parsedTypesIn)
1450+
1451+
name_ptr := decodePtrSizeBytes(imethoddata[0:ptrSize], is64bit, littleendian)
1452+
name, err := e.readRTypeName(runtimeVersion, 0, name_ptr, is64bit, littleendian)
1453+
if err != nil {
1454+
continue
1455+
}
1456+
14501457
methodfunc, found := parsedTypesIn.Get(typeAddr)
14511458
if found {
1452-
interfaceDef += "\nmethod" + strconv.Itoa(i) + " " + methodfunc.(Type).Str
1453-
cinterfaceDef += methodfunc.(Type).CStr + "method" + strconv.Itoa(i) + ";\n"
1459+
interfaceDef += strings.Replace(methodfunc.(Type).Str, "func", name, 1) + "\n"
1460+
cinterfaceDef += methodfunc.(Type).CStr + " " + name + ";\n"
14541461
}
14551462
}
14561463
interfaceDef += "\n}"
@@ -1513,7 +1520,7 @@ func (e *Entry) ParseType_impl(runtimeVersion string, moduleData *ModuleData, ty
15131520
interfaceDef := "type interface {"
15141521
cinterfaceDef := "struct interface {\n"
15151522
(*_type).CStr = "interface_"
1516-
if *&_type.flags&tflagNamed != 0 {
1523+
if _type.flags&tflagNamed != 0 {
15171524
interfaceDef = fmt.Sprintf("type %s interface {", _type.Str)
15181525
cinterfaceDef = fmt.Sprintf("struct %s_interface {\n", _type.CStr)
15191526
(*_type).CStr = fmt.Sprintf("%s_interface", _type.CStr)
@@ -1539,10 +1546,16 @@ func (e *Entry) ParseType_impl(runtimeVersion string, moduleData *ModuleData, ty
15391546
typeAddr := moduleData.Types + uint64(method.Typ)
15401547
parsedTypesIn, _ = e.ParseType_impl(runtimeVersion, moduleData, typeAddr, is64bit, littleendian, parsedTypesIn)
15411548

1549+
name_ptr := moduleData.Types + uint64(method.Name)
1550+
name, err := e.readRTypeName(runtimeVersion, 0, name_ptr, is64bit, littleendian)
1551+
if err != nil {
1552+
continue
1553+
}
1554+
15421555
methodfunc, found := parsedTypesIn.Get(typeAddr)
15431556
if found {
1544-
interfaceDef += "\nmethod" + strconv.Itoa(i) + " " + methodfunc.(Type).Str
1545-
cinterfaceDef += methodfunc.(Type).CStr + " method" + strconv.Itoa(i) + ";\n"
1557+
interfaceDef += strings.Replace(methodfunc.(Type).Str, "func", name, 1) + "\n"
1558+
cinterfaceDef += methodfunc.(Type).CStr + " " + name + ";\n"
15461559
}
15471560
}
15481561
interfaceDef += "\n}"

0 commit comments

Comments
 (0)