From f238d3b9fa149264891510b7b30024040b8a8c8f Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Thu, 10 Oct 2019 12:11:06 -0400 Subject: [PATCH] [release-branch.go1.13] cmd/compile: fix spurious R_TLE_LE reloc on android/386 When compiling for GOARCH=386 GOOS=android, the compiler was attaching R_TLS_LE relocations inappropriately -- as of Go 1.13 the TLS access recipe for Android refers to a runtime symbol and no longer needs this type of relocation (which was causing a crash when the linker tried to process it). Fixes #34825. Change-Id: Ida01875011b524586597b1f7e273aa14e11815d6 Reviewed-on: https://go-review.googlesource.com/c/go/+/200337 Run-TryBot: Than McIntosh TryBot-Result: Gobot Gobot Reviewed-by: Elias Naur Reviewed-by: Cherry Zhang Reviewed-on: https://go-review.googlesource.com/c/go/+/204100 --- src/cmd/internal/obj/x86/asm6.go | 2 +- src/cmd/link/link_test.go | 61 ++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go index 1f668a0166..39e67c6ff3 100644 --- a/src/cmd/internal/obj/x86/asm6.go +++ b/src/cmd/internal/obj/x86/asm6.go @@ -3514,7 +3514,7 @@ func (ab *AsmBuf) asmandsz(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a *obj } if REG_AX <= base && base <= REG_R15 { - if a.Index == REG_TLS && !ctxt.Flag_shared { + if a.Index == REG_TLS && !ctxt.Flag_shared && !isAndroid { rel = obj.Reloc{} rel.Type = objabi.R_TLS_LE rel.Siz = 4 diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go index 29b98e9c32..155fd8bce3 100644 --- a/src/cmd/link/link_test.go +++ b/src/cmd/link/link_test.go @@ -1,6 +1,8 @@ package main import ( + "bufio" + "bytes" "debug/macho" "internal/testenv" "io/ioutil" @@ -315,3 +317,62 @@ func TestMacOSVersion(t *testing.T) { t.Errorf("no LC_VERSION_MIN_MACOSX load command found") } } + +const Issue34788src = ` + +package blah + +func Blah(i int) int { + a := [...]int{1, 2, 3, 4, 5, 6, 7, 8} + return a[i&7] +} +` + +func TestIssue34788Android386TLSSequence(t *testing.T) { + testenv.MustHaveGoBuild(t) + + // This is a cross-compilation test, so it doesn't make + // sense to run it on every GOOS/GOARCH combination. Limit + // the test to amd64 + darwin/linux. + if runtime.GOARCH != "amd64" || + (runtime.GOOS != "darwin" && runtime.GOOS != "linux") { + t.Skip("skipping on non-{linux,darwin}/amd64 platform") + } + + tmpdir, err := ioutil.TempDir("", "TestIssue34788Android386TLSSequence") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + src := filepath.Join(tmpdir, "blah.go") + err = ioutil.WriteFile(src, []byte(Issue34788src), 0666) + if err != nil { + t.Fatal(err) + } + + obj := filepath.Join(tmpdir, "blah.o") + cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-o", obj, src) + cmd.Env = append(os.Environ(), "GOARCH=386", "GOOS=android") + if out, err := cmd.CombinedOutput(); err != nil { + if err != nil { + t.Fatalf("failed to compile blah.go: %v, output: %s\n", err, out) + } + } + + // Run objdump on the resulting object. + cmd = exec.Command(testenv.GoToolPath(t), "tool", "objdump", obj) + out, oerr := cmd.CombinedOutput() + if oerr != nil { + t.Fatalf("failed to objdump blah.o: %v, output: %s\n", oerr, out) + } + + // Sift through the output; we should not be seeing any R_TLS_LE relocs. + scanner := bufio.NewScanner(bytes.NewReader(out)) + for scanner.Scan() { + line := scanner.Text() + if strings.Contains(line, "R_TLS_LE") { + t.Errorf("objdump output contains unexpected R_TLS_LE reloc: %s", line) + } + } +} -- 2.48.1