Commit 688aa748 authored by Than McIntosh's avatar Than McIntosh

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/+/208478Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
parent f29e53d6
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package main package main
import ( import (
"fmt"
"internal/testenv" "internal/testenv"
"io/ioutil" "io/ioutil"
"os" "os"
...@@ -16,6 +17,27 @@ import ( ...@@ -16,6 +17,27 @@ import (
"testing" "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 = ` var asmSource = `
.section .text1,"ax" .section .text1,"ax"
s1: s1:
...@@ -61,21 +83,7 @@ func TestSectionsWithSameName(t *testing.T) { ...@@ -61,21 +83,7 @@ func TestSectionsWithSameName(t *testing.T) {
} }
goTool := testenv.GoToolPath(t) goTool := testenv.GoToolPath(t)
cmd := exec.Command(goTool, "env", "CC") cc, cflags := getCCAndCCFLAGS(t, env)
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))
asmObj := filepath.Join(dir, "x.o") asmObj := filepath.Join(dir, "x.o")
t.Logf("%s %v -c -o %s %s", cc, cflags, asmObj, asmFile) t.Logf("%s %v -c -o %s %s", cc, cflags, asmObj, asmFile)
...@@ -102,7 +110,91 @@ func TestSectionsWithSameName(t *testing.T) { ...@@ -102,7 +110,91 @@ func TestSectionsWithSameName(t *testing.T) {
t.Fatal(err) 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.Dir = dir
cmd.Env = env cmd.Env = env
t.Logf("%s build", goTool) t.Logf("%s build", goTool)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment