github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/internal/obj/x86/pcrelative_test.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package x86_test 6 7 import ( 8 "bytes" 9 "fmt" 10 "github.com/gagliardetto/golang-go/not-internal/testenv" 11 "io/ioutil" 12 "os" 13 "os/exec" 14 "path/filepath" 15 "testing" 16 ) 17 18 const asmData = ` 19 GLOBL zeros<>(SB),8,$64 20 TEXT ·testASM(SB),4,$0 21 VMOVUPS zeros<>(SB), %s // PC relative relocation is off by 1, for Y8-Y15, Z8-15 and Z24-Z31 22 RET 23 ` 24 25 const goData = ` 26 package main 27 28 func testASM() 29 30 func main() { 31 testASM() 32 } 33 ` 34 35 func objdumpOutput(t *testing.T, mname, source string) []byte { 36 tmpdir, err := ioutil.TempDir("", mname) 37 if err != nil { 38 t.Fatal(err) 39 } 40 defer os.RemoveAll(tmpdir) 41 err = ioutil.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte(fmt.Sprintf("module %s\n", mname)), 0666) 42 if err != nil { 43 t.Fatal(err) 44 } 45 tmpfile, err := os.Create(filepath.Join(tmpdir, "input.s")) 46 if err != nil { 47 t.Fatal(err) 48 } 49 defer tmpfile.Close() 50 _, err = tmpfile.WriteString(source) 51 if err != nil { 52 t.Fatal(err) 53 } 54 tmpfile2, err := os.Create(filepath.Join(tmpdir, "input.go")) 55 if err != nil { 56 t.Fatal(err) 57 } 58 defer tmpfile2.Close() 59 _, err = tmpfile2.WriteString(goData) 60 if err != nil { 61 t.Fatal(err) 62 } 63 64 cmd := exec.Command( 65 testenv.GoToolPath(t), "build", "-o", 66 filepath.Join(tmpdir, "output")) 67 68 cmd.Env = append(os.Environ(), 69 "GOARCH=amd64", "GOOS=linux", "GOPATH="+filepath.Join(tmpdir, "_gopath")) 70 cmd.Dir = tmpdir 71 72 out, err := cmd.CombinedOutput() 73 if err != nil { 74 t.Fatalf("error %s output %s", err, out) 75 } 76 cmd2 := exec.Command( 77 testenv.GoToolPath(t), "tool", "objdump", "-s", "testASM", 78 filepath.Join(tmpdir, "output")) 79 cmd2.Env = cmd.Env 80 cmd2.Dir = tmpdir 81 objout, err := cmd2.CombinedOutput() 82 if err != nil { 83 t.Fatalf("error %s output %s", err, objout) 84 } 85 86 return objout 87 } 88 89 func TestVexEvexPCrelative(t *testing.T) { 90 testenv.MustHaveGoBuild(t) 91 LOOP: 92 for _, reg := range []string{"Y0", "Y8", "Z0", "Z8", "Z16", "Z24"} { 93 asm := fmt.Sprintf(asmData, reg) 94 objout := objdumpOutput(t, "pcrelative", asm) 95 data := bytes.Split(objout, []byte("\n")) 96 for idx := len(data) - 1; idx >= 0; idx-- { 97 // check that RET wasn't overwritten. 98 if bytes.Index(data[idx], []byte("RET")) != -1 { 99 if testing.Short() { 100 break LOOP 101 } 102 continue LOOP 103 } 104 } 105 t.Errorf("VMOVUPS zeros<>(SB), %s overwrote RET", reg) 106 } 107 }