summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-09-30 13:47:15 -0700
committerRuss Cox <rsc@golang.org>2009-09-30 13:47:15 -0700
commit872a8a09080aee0bb54eddf8cbc3d57a61aec6ab (patch)
tree8e798c970bfa78770ae32e343c2b5807dcbbb2da
parentcea1e9d746c5013b6566fac3a06f817626fbcae1 (diff)
downloadgolang-872a8a09080aee0bb54eddf8cbc3d57a61aec6ab.tar.gz
cgo working on linux/386
R=r DELTA=70 (47 added, 4 deleted, 19 changed) OCL=35167 CL=35171
-rw-r--r--misc/cgo/gmp/Makefile6
-rw-r--r--src/Make.pkg9
-rw-r--r--src/cmd/8c/swt.c11
-rw-r--r--src/cmd/8l/asm.c11
-rw-r--r--src/cmd/cgo/ast.go1
-rw-r--r--src/cmd/cgo/gcc.go12
-rw-r--r--src/cmd/cgo/main.go18
-rw-r--r--src/cmd/cgo/out.go8
-rw-r--r--src/libcgo/Makefile6
-rwxr-xr-xsrc/pkg/runtime/linux/386/rt0.s7
10 files changed, 66 insertions, 23 deletions
diff --git a/misc/cgo/gmp/Makefile b/misc/cgo/gmp/Makefile
index 1e521ab7d..b261ff235 100644
--- a/misc/cgo/gmp/Makefile
+++ b/misc/cgo/gmp/Makefile
@@ -10,6 +10,12 @@ CGOFILES=\
CGO_LDFLAGS=-lgmp
+# To add flags necessary for locating the library or its include files,
+# set CGO_CFLAGS or CGO_LDFLAGS. For example, to use an
+# alternate installation of the library:
+# CGO_CFLAGS=-I/home/rsc/gmp32/include
+# CGO_LDFLAGS+=-L/home/rsc/gmp32/lib
+
# Can have plain GOFILES too, but this example doesn't.
include $(GOROOT)/src/Make.pkg
diff --git a/src/Make.pkg b/src/Make.pkg
index fadd78e3d..bc00eeaef 100644
--- a/src/Make.pkg
+++ b/src/Make.pkg
@@ -93,18 +93,21 @@ RUNTIME_CFLAGS=-I$(GOROOT)/src/pkg/runtime $(RUNTIME_CFLAGS_$(GOARCH))
%.cgo3.$O: %.cgo3.c
$(CC) $(CFLAGS) $(RUNTIME_CFLAGS) $*.cgo3.c
+# Have to run gcc with the right size argument on hybrid 32/64 machines.
+_CGO_CFLAGS_386=-m32
+_CGO_CFLAGS_amd64=-m64
+
# Compile x.cgo4.c with gcc to make package_x.so.
%.cgo4.o: %.cgo4.c
- gcc -fPIC -O2 -o $@ -c $(CGO_CFLAGS) $*.cgo4.c
+ gcc $(_CGO_CFLAGS_$(GOARCH)) -fPIC -O2 -o $@ -c $(CGO_CFLAGS) $*.cgo4.c
$(elem)_%.so: %.cgo4.o
- gcc -shared -o $@ $*.cgo4.o $(CGO_LDFLAGS)
+ gcc $(_CGO_CFLAGS_$(GOARCH)) -shared -o $@ $*.cgo4.o $(CGO_LDFLAGS)
$(pkgdir)/$(dir)/$(elem)_%.so: $(elem)_%.so
@test -d $(GOROOT)/pkg && mkdir -p $(pkgdir)/$(dir)
cp $(elem)_$*.so $@
-
# Generic build rules.
# These come last so that the rules above can override them
# for more specific file names.
diff --git a/src/cmd/8c/swt.c b/src/cmd/8c/swt.c
index dc7caf3ec..76dc19947 100644
--- a/src/cmd/8c/swt.c
+++ b/src/cmd/8c/swt.c
@@ -231,6 +231,17 @@ outcode(void)
Binit(&b, f, OWRITE);
Bprint(&b, "%s\n", thestring);
+ if(ndynld > 0) {
+ int i;
+
+ Bprint(&b, "\n");
+ Bprint(&b, "$$ // exports\n\n");
+ Bprint(&b, "$$ // local types\n\n");
+ Bprint(&b, "$$ // dynld\n", thestring);
+ for(i=0; i<ndynld; i++)
+ Bprint(&b, "dynld %s %s %s\n", dynld[i].local, dynld[i].remote, dynld[i].path);
+ Bprint(&b, "$$\n\n");
+ }
Bprint(&b, "!\n");
outhist(&b);
diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c
index f5a73884d..627bd25e8 100644
--- a/src/cmd/8l/asm.c
+++ b/src/cmd/8l/asm.c
@@ -333,7 +333,7 @@ doelf(void)
s = lookup(".dynsym", 0);
s->type = SDATA;
s->reachable = 1;
- s->value += ELF64SYMSIZE;
+ s->value += ELF32SYMSIZE;
/* dynamic string table */
s = lookup(".dynstr", 0);
@@ -368,21 +368,20 @@ doelf(void)
if(!s->reachable || (s->type != SDATA && s->type != SBSS) || s->dynldname == nil)
continue;
- d = lookup(".rela", 0);
+ d = lookup(".rel", 0);
addaddr(d, s);
- adduint64(d, ELF64_R_INFO(nsym, R_X86_64_64));
- adduint64(d, 0);
+ adduint32(d, ELF32_R_INFO(nsym, R_386_32));
nsym++;
d = lookup(".dynsym", 0);
adduint32(d, addstring(lookup(".dynstr", 0), s->dynldname));
+ adduint32(d, 0); /* value */
+ adduint32(d, 0); /* size of object */
t = STB_GLOBAL << 4;
t |= STT_OBJECT; // works for func too, empirically
adduint8(d, t);
adduint8(d, 0); /* reserved */
adduint16(d, SHN_UNDEF); /* section where symbol is defined */
- adduint64(d, 0); /* value */
- adduint64(d, 0); /* size of object */
if(needlib(s->dynldlib))
elfwritedynent(dynamic, DT_NEEDED, addstring(dynstr, s->dynldlib));
diff --git a/src/cmd/cgo/ast.go b/src/cmd/cgo/ast.go
index 29fe55240..9b122676c 100644
--- a/src/cmd/cgo/ast.go
+++ b/src/cmd/cgo/ast.go
@@ -35,6 +35,7 @@ type Prog struct {
Typedef map[string]ast.Expr;
Vardef map[string]*Type;
Funcdef map[string]*FuncType;
+ PtrSize int64;
}
// A Type collects information about a type in both the C and Go worlds.
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index 27090fdf4..e3f526845 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -20,7 +20,7 @@ import (
"strings";
)
-func (p *Prog) loadDebugInfo(ptrSize int64) {
+func (p *Prog) loadDebugInfo() {
// Construct a slice of unique names from p.Crefs.
m := make(map[string]int);
for _, c := range p.Crefs {
@@ -57,7 +57,7 @@ func (p *Prog) loadDebugInfo(ptrSize int64) {
b.WriteString("}\n");
kind := make(map[string]string);
- _, stderr := gccDebug(b.Bytes());
+ _, stderr := p.gccDebug(b.Bytes());
if stderr == "" {
fatal("gcc produced no output");
}
@@ -109,7 +109,7 @@ func (p *Prog) loadDebugInfo(ptrSize int64) {
for i, n := range names {
fmt.Fprintf(&b, "typeof(%s) *__cgo__%d;\n", n, i);
}
- d, stderr := gccDebug(b.Bytes());
+ d, stderr := p.gccDebug(b.Bytes());
if d == nil {
fatal("gcc failed:\n%s\non input:\n%s", stderr, b.Bytes());
}
@@ -158,7 +158,7 @@ func (p *Prog) loadDebugInfo(ptrSize int64) {
// Record types and typedef information in Crefs.
var conv typeConv;
- conv.Init(ptrSize);
+ conv.Init(p.PtrSize);
for _, c := range p.Crefs {
i := m[c.Name];
c.TypeName = kind[c.Name] == "type";
@@ -175,9 +175,9 @@ func (p *Prog) loadDebugInfo(ptrSize int64) {
// gccDebug runs gcc -gdwarf-2 over the C program stdin and
// returns the corresponding DWARF data and any messages
// printed to standard error.
-func gccDebug(stdin []byte) (*dwarf.Data, string) {
+func (p *Prog) gccDebug(stdin []byte) (*dwarf.Data, string) {
machine := "-m32";
- if os.Getenv("GOARCH") == "amd64" {
+ if p.PtrSize == 8 {
machine = "-m64";
}
diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go
index 0832b3f40..b629f0a22 100644
--- a/src/cmd/cgo/main.go
+++ b/src/cmd/cgo/main.go
@@ -22,20 +22,34 @@ func usage() {
flag.PrintDefaults();
}
-const ptrSize = 8 // TODO
+var ptrSizeMap = map[string]int64 {
+ "386": 4,
+ "amd64": 8,
+ "arm": 4
+}
func main() {
flag.Usage = usage;
flag.Parse();
+ arch := os.Getenv("GOARCH");
+ if arch == "" {
+ fatal("$GOARCH is not set");
+ }
+ ptrSize, ok := ptrSizeMap[arch];
+ if !ok {
+ fatal("unknown architecture %s", arch);
+ }
+
args := flag.Args();
if len(args) != 1 {
usage();
os.Exit(2);
}
p := openProg(args[0]);
+ p.PtrSize = ptrSize;
p.Preamble = p.Preamble + "\n" + builtinProlog;
- p.loadDebugInfo(ptrSize);
+ p.loadDebugInfo();
p.Vardef = make(map[string]*Type);
p.Funcdef = make(map[string]*FuncType);
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index 36fbe0349..91473abeb 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -100,8 +100,8 @@ func (p *Prog) writeOutput(srcfile string) {
structType += fmt.Sprintf("\t\t%s p%d;\n", t.C, i);
off += t.Size;
}
- if off%ptrSize != 0 {
- pad := ptrSize - off%ptrSize;
+ if off%p.PtrSize != 0 {
+ pad := p.PtrSize - off%p.PtrSize;
structType += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad);
off += pad;
npad++;
@@ -116,8 +116,8 @@ func (p *Prog) writeOutput(srcfile string) {
structType += fmt.Sprintf("\t\t%s r;\n", t.C);
off += t.Size;
}
- if off%ptrSize != 0 {
- pad := ptrSize - off%ptrSize;
+ if off%p.PtrSize != 0 {
+ pad := p.PtrSize - off%p.PtrSize;
structType += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad);
off += pad;
npad++;
diff --git a/src/libcgo/Makefile b/src/libcgo/Makefile
index 6fbfeb067..ea4ccc7ef 100644
--- a/src/libcgo/Makefile
+++ b/src/libcgo/Makefile
@@ -4,15 +4,17 @@
# not linked into build for now
+CFLAGS_386=-m32
+
TARG=libcgo.so
all: libcgo.so
cgocall.o: cgocall.c
- gcc -O2 -fPIC -o cgocall.o -c cgocall.c
+ gcc $(CFLAGS_$(GOARCH)) -O2 -fPIC -o cgocall.o -c cgocall.c
libcgo.so: cgocall.o
- gcc -shared -o libcgo.so cgocall.o -lpthread -lm
+ gcc $(CFLAGS_$(GOARCH)) -shared -o libcgo.so cgocall.o -lpthread -lm
install: $(GOROOT)/pkg/$(GOOS)_$(GOARCH)/libcgo.so
diff --git a/src/pkg/runtime/linux/386/rt0.s b/src/pkg/runtime/linux/386/rt0.s
index 7717c37e8..d5d270be2 100755
--- a/src/pkg/runtime/linux/386/rt0.s
+++ b/src/pkg/runtime/linux/386/rt0.s
@@ -5,4 +5,11 @@
// Darwin and Linux use the same linkage to main
TEXT _rt0_386_linux(SB),7,$0
+ MOVL initcgo(SB), AX
+ TESTL AX, AX
+ JZ 2(PC)
+ CALL AX
+
JMP _rt0_386(SB)
+
+GLOBL initcgo(SB), $4