mirror of
https://github.com/golang/go
synced 2024-11-17 06:04:47 -07:00
cmd/link: add new linker testpoint for "ld -r" host object
This adds a new test that builds a small Go program with linked against a *.syso file that is the result of an "ld -r" link. The sysobj in question has multiple static symbols in the same section with the same name, which triggered a bug in the loader in -newobj mode. Updates #35779. Change-Id: Ibe1a75662dc1d49c4347279e55646ee65a81508e Reviewed-on: https://go-review.googlesource.com/c/go/+/208478 Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
f29e53d664
commit
688aa74857
@ -7,6 +7,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"internal/testenv"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -16,6 +17,27 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func getCCAndCCFLAGS(t *testing.T, env []string) (string, []string) {
|
||||
goTool := testenv.GoToolPath(t)
|
||||
cmd := exec.Command(goTool, "env", "CC")
|
||||
cmd.Env = env
|
||||
ccb, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cc := strings.TrimSpace(string(ccb))
|
||||
|
||||
cmd = exec.Command(goTool, "env", "GOGCCFLAGS")
|
||||
cmd.Env = env
|
||||
cflagsb, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cflags := strings.Fields(string(cflagsb))
|
||||
|
||||
return cc, cflags
|
||||
}
|
||||
|
||||
var asmSource = `
|
||||
.section .text1,"ax"
|
||||
s1:
|
||||
@ -61,21 +83,7 @@ func TestSectionsWithSameName(t *testing.T) {
|
||||
}
|
||||
|
||||
goTool := testenv.GoToolPath(t)
|
||||
cmd := exec.Command(goTool, "env", "CC")
|
||||
cmd.Env = env
|
||||
ccb, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cc := strings.TrimSpace(string(ccb))
|
||||
|
||||
cmd = exec.Command(goTool, "env", "GOGCCFLAGS")
|
||||
cmd.Env = env
|
||||
cflagsb, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cflags := strings.Fields(string(cflagsb))
|
||||
cc, cflags := getCCAndCCFLAGS(t, env)
|
||||
|
||||
asmObj := filepath.Join(dir, "x.o")
|
||||
t.Logf("%s %v -c -o %s %s", cc, cflags, asmObj, asmFile)
|
||||
@ -102,7 +110,91 @@ func TestSectionsWithSameName(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cmd = exec.Command(goTool, "build")
|
||||
cmd := exec.Command(goTool, "build")
|
||||
cmd.Dir = dir
|
||||
cmd.Env = env
|
||||
t.Logf("%s build", goTool)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Logf("%s", out)
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
var cSources35779 = []string{`
|
||||
static int blah() { return 42; }
|
||||
int Cfunc1() { return blah(); }
|
||||
`, `
|
||||
static int blah() { return 42; }
|
||||
int Cfunc2() { return blah(); }
|
||||
`,
|
||||
}
|
||||
|
||||
// TestMinusRSymsWithSameName tests a corner case in the new
|
||||
// loader. Prior to the fix this failed with the error 'loadelf:
|
||||
// $WORK/b001/_pkg_.a(ldr.syso): duplicate symbol reference: blah in
|
||||
// both main(.text) and main(.text)'
|
||||
func TestMinusRSymsWithSameName(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
testenv.MustHaveCGO(t)
|
||||
t.Parallel()
|
||||
|
||||
dir, err := ioutil.TempDir("", "go-link-TestMinusRSymsWithSameName")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
gopath := filepath.Join(dir, "GOPATH")
|
||||
env := append(os.Environ(), "GOPATH="+gopath)
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte("module elf_test\n"), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
goTool := testenv.GoToolPath(t)
|
||||
cc, cflags := getCCAndCCFLAGS(t, env)
|
||||
|
||||
objs := []string{}
|
||||
csrcs := []string{}
|
||||
for i, content := range cSources35779 {
|
||||
csrcFile := filepath.Join(dir, fmt.Sprintf("x%d.c", i))
|
||||
csrcs = append(csrcs, csrcFile)
|
||||
if err := ioutil.WriteFile(csrcFile, []byte(content), 0444); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
obj := filepath.Join(dir, fmt.Sprintf("x%d.o", i))
|
||||
objs = append(objs, obj)
|
||||
t.Logf("%s %v -c -o %s %s", cc, cflags, obj, csrcFile)
|
||||
if out, err := exec.Command(cc, append(cflags, "-c", "-o", obj, csrcFile)...).CombinedOutput(); err != nil {
|
||||
t.Logf("%s", out)
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
sysoObj := filepath.Join(dir, "ldr.syso")
|
||||
t.Logf("%s %v -nostdlib -r -o %s %v", cc, cflags, sysoObj, objs)
|
||||
if out, err := exec.Command(cc, append(cflags, "-nostdlib", "-r", "-o", sysoObj, objs[0], objs[1])...).CombinedOutput(); err != nil {
|
||||
t.Logf("%s", out)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cruft := [][]string{objs, csrcs}
|
||||
for _, sl := range cruft {
|
||||
for _, s := range sl {
|
||||
if err := os.Remove(s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goFile := filepath.Join(dir, "main.go")
|
||||
if err := ioutil.WriteFile(goFile, []byte(goSource), 0444); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Logf("%s build", goTool)
|
||||
cmd := exec.Command(goTool, "build")
|
||||
cmd.Dir = dir
|
||||
cmd.Env = env
|
||||
t.Logf("%s build", goTool)
|
||||
|
Loading…
Reference in New Issue
Block a user