]> Cypherpunks repositories - gostls13.git/commitdiff
cgo: avoid self-interference of global names
authorRuss Cox <rsc@golang.org>
Fri, 10 Dec 2010 19:32:58 +0000 (11:32 -0800)
committerRuss Cox <rsc@golang.org>
Fri, 10 Dec 2010 19:32:58 +0000 (11:32 -0800)
Fixes #1332.

R=iant, iant2
CC=golang-dev
https://golang.org/cl/3555041

src/cmd/cgo/main.go
src/cmd/cgo/out.go

index ef7275023abbb521a68aeb3e66256bd88115c57a..cbc9d16da585fb23b28ad8d6be994848f71a4cd6 100644 (file)
 package main
 
 import (
+       "crypto/md5"
        "flag"
        "fmt"
        "go/ast"
        "go/token"
+       "io"
        "os"
        "reflect"
        "strings"
@@ -105,6 +107,8 @@ var ptrSizeMap = map[string]int64{
        "arm":   4,
 }
 
+var cPrefix string
+
 var fset = token.NewFileSet()
 
 var dynobj = flag.String("dynimport", "", "if non-empty, print dynamic import data for that file")
@@ -170,6 +174,22 @@ func main() {
                Written:    make(map[string]bool),
        }
 
+       // Need a unique prefix for the global C symbols that
+       // we use to coordinate between gcc and ourselves.
+       // We already put _cgo_ at the beginning, so the main
+       // concern is other cgo wrappers for the same functions.
+       // Use the beginning of the md5 of the input to disambiguate.
+       h := md5.New()
+       for _, input := range goFiles {
+               f, err := os.Open(input, os.O_RDONLY, 0)
+               if err != nil {
+                       fatal("%s", err)
+               }
+               io.Copy(h, f)
+               f.Close()
+       }
+       cPrefix = fmt.Sprintf("_%x", h.Sum()[0:6])
+
        for _, input := range goFiles {
                f := new(File)
                // Reset f.Preamble so that we don't end up with conflicting headers / defines
index c7db2c7cc08e76672a4e3ed4764485d4f97b1a86..d6b25d5c193421d4b95b4acf5ba1f91db013aee7 100644 (file)
@@ -212,12 +212,12 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name, soprefix, sopath str
        _, argSize = p.structType(n)
 
        // C wrapper calls into gcc, passing a pointer to the argument frame.
-       fmt.Fprintf(fc, "void _cgo%s(void*);\n", n.Mangle)
+       fmt.Fprintf(fc, "void _cgo%s%s(void*);\n", cPrefix, n.Mangle)
        fmt.Fprintf(fc, "\n")
        fmt.Fprintf(fc, "void\n")
        fmt.Fprintf(fc, "·%s(struct{uint8 x[%d];}p)\n", n.Mangle, argSize)
        fmt.Fprintf(fc, "{\n")
-       fmt.Fprintf(fc, "\truntime·cgocall(_cgo%s, &p);\n", n.Mangle)
+       fmt.Fprintf(fc, "\truntime·cgocall(_cgo%s%s, &p);\n", cPrefix, n.Mangle)
        if n.AddError {
                // gcc leaves errno in first word of interface at end of p.
                // check whether it is zero; if so, turn interface into nil.
@@ -292,7 +292,7 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
        // Gcc wrapper unpacks the C argument struct
        // and calls the actual C function.
        fmt.Fprintf(fgcc, "void\n")
-       fmt.Fprintf(fgcc, "_cgo%s(void *v)\n", n.Mangle)
+       fmt.Fprintf(fgcc, "_cgo%s%s(void *v)\n", cPrefix, n.Mangle)
        fmt.Fprintf(fgcc, "{\n")
        if n.AddError {
                fmt.Fprintf(fgcc, "\tint e;\n") // assuming 32 bit (see comment above structType)