initial support for cgo

I'm sure that the added test case doesn't cover many edge cases, but
it's a start.

Fixes #12.
pull/22/head
Daniel Martí 4 years ago
parent 5aaa086e5d
commit 04dea79b2d

@ -287,8 +287,18 @@ func transformCompile(args []string) ([]string, error) {
args = flags
// TODO: randomize the order and names of the files
for i, file := range files {
file := transformGo(file, info)
tempFile := filepath.Join(tempDir, fmt.Sprintf("z%d.go", i))
origName := filepath.Base(filepath.Clean(paths[i]))
name := fmt.Sprintf("z%d.go", i)
switch {
case strings.HasPrefix(origName, "_cgo_"):
// Cgo generated code requires a prefix. Also, don't
// garble it, since it's just generated code and it gets
// messy.
name = "_cgo_" + name
default:
file = transformGo(file, info)
}
tempFile := filepath.Join(tempDir, name)
f, err := os.Create(tempFile)
if err != nil {
return nil, err
@ -384,7 +394,7 @@ func hashWith(salt, value string) string {
}
// transformGo garbles the provided Go syntax node.
func transformGo(file *ast.File, info *types.Info) ast.Node {
func transformGo(file *ast.File, info *types.Info) *ast.File {
// Remove all comments, minus the "//go:" compiler directives.
// The final binary should still not contain comment text, but removing
// it helps ensure that (and makes position info less predictable).
@ -406,6 +416,9 @@ func transformGo(file *ast.File, info *types.Info) ast.Node {
if node.Name == "_" {
return true // unnamed remains unnamed
}
if strings.HasPrefix(node.Name, "_C") || strings.Contains(node.Name, "_cgo") {
return true // don't mess with cgo-generated code
}
obj := info.ObjectOf(node)
// log.Printf("%#v %T", node, obj)
switch x := obj.(type) {
@ -473,7 +486,7 @@ func transformGo(file *ast.File, info *types.Info) ast.Node {
}
return true
}
return astutil.Apply(file, pre, nil)
return astutil.Apply(file, pre, nil).(*ast.File)
}
func isStandardLibrary(path string) bool {

@ -0,0 +1,30 @@
garble build
exec ./main
cmp stdout main.stdout
binsubstr main$exe 'privateAdd'
[short] stop # no need to verify this with -short
go build
exec ./main
cmp stdout main.stdout
-- go.mod --
module foo.com/main
-- main.go --
package main
/*
static int privateAdd(int a, int b) {
return a + b;
}
*/
import "C"
import "fmt"
func main() {
fmt.Println(C.privateAdd(C.int(1), C.int(2)))
}
-- main.stdout --
3
Loading…
Cancel
Save