avoid patching our reflect code into _cgo_gotypes.go

When obfuscating a main package whose Go files all import "C",
the first Go file in CompiledGoFiles ends up being _cgo_gotypes.go.
We cannot add our code from reflect_abi_code.go there,
as it leads to the following error about its _trieNode type:

    typecheck error: $WORK/b001/_cgo_gotypes.go:185:10: cannot define new methods on non-local type _trieNode

Avoid patching any _cgo_*.go file with our reflect code,
as all of those files are special glue code for cgo.

While here, tweak reflectMainPrePatch to return a string
for consistency with abiNamePatch.

Fixes #916.
pull/943/head
Daniel Martí 6 months ago committed by Paul Scheduikat
parent b5d90cb1bd
commit b34a7e3926

@ -922,12 +922,14 @@ func parseFiles(lpkg *listedPackage, dir string, paths []string) (files []*ast.F
var src any var src any
if lpkg.ImportPath == "internal/abi" && filepath.Base(path) == "type.go" { base := filepath.Base(path)
if lpkg.ImportPath == "internal/abi" && base == "type.go" {
src, err = abiNamePatch(path) src, err = abiNamePatch(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else if mainPackage && reflectPatchFile == "" { } else if mainPackage && reflectPatchFile == "" && !strings.HasPrefix(base, "_cgo_") {
// Note that we cannot add our code to e.g. _cgo_gotypes.go.
src, err = reflectMainPrePatch(path) src, err = reflectMainPrePatch(path)
if err != nil { if err != nil {
return nil, err return nil, err
@ -941,12 +943,15 @@ func parseFiles(lpkg *listedPackage, dir string, paths []string) (files []*ast.F
return nil, err return nil, err
} }
if mainPackage && src != nil { if mainPackage && src != "" {
astutil.AddNamedImport(fset, file, "_", "unsafe") astutil.AddNamedImport(fset, file, "_", "unsafe")
} }
files = append(files, file) files = append(files, file)
} }
if mainPackage && reflectPatchFile == "" {
return nil, fmt.Errorf("main packages must get reflect code patched in")
}
return files, nil return files, nil
} }

@ -43,21 +43,21 @@ var reflectPatchFile = ""
// We split this into pre/post steps so that all variable names in the generated code // We split this into pre/post steps so that all variable names in the generated code
// can be properly obfuscated - if we added the filled map directly, the obfuscated names // can be properly obfuscated - if we added the filled map directly, the obfuscated names
// would appear as plain strings in the binary. // would appear as plain strings in the binary.
func reflectMainPrePatch(path string) ([]byte, error) { func reflectMainPrePatch(path string) (string, error) {
if reflectPatchFile != "" { if reflectPatchFile != "" {
// already patched another file in main // already patched another file in main
return nil, nil return "", nil
} }
content, err := os.ReadFile(path) content, err := os.ReadFile(path)
if err != nil { if err != nil {
return nil, err return "", err
} }
_, code, _ := strings.Cut(reflectAbiCode, "// Injected code below this line.") _, code, _ := strings.Cut(reflectAbiCode, "// Injected code below this line.")
code = strings.ReplaceAll(code, "//disabledgo:", "//go:") code = strings.ReplaceAll(code, "//disabledgo:", "//go:")
// This constant is declared in our hash.go file. // This constant is declared in our hash.go file.
code = strings.ReplaceAll(code, "minHashLength", strconv.Itoa(minHashLength)) code = strings.ReplaceAll(code, "minHashLength", strconv.Itoa(minHashLength))
return append(content, []byte(code)...), nil return string(content) + code, nil
} }
// reflectMainPostPatch populates the name mapping with the final obfuscated->real name // reflectMainPostPatch populates the name mapping with the final obfuscated->real name

@ -1,8 +1,6 @@
[!cgo] skip 'this test requires cgo to be enabled' [!cgo] skip 'this test requires cgo to be enabled'
! exec garble build exec garble build
stderr 'cannot define new methods on non-local type _trieNode'
stop
! stderr 'warning' # check that the C toolchain is happy ! stderr 'warning' # check that the C toolchain is happy
exec ./main exec ./main
cmp stdout main.stdout cmp stdout main.stdout

Loading…
Cancel
Save