github.com/gernest/nezuko@v0.1.2/internal/obj/x86/issue19518_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 "internal/testenv" 10 "io/ioutil" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "testing" 15 ) 16 17 const asmData = ` 18 GLOBL zeros<>(SB),8,$64 19 TEXT ·testASM(SB),4,$0 20 VMOVDQU zeros<>(SB), Y8 // PC relative relocation is off by 1, for Y8-15 21 RET 22 ` 23 24 const goData = ` 25 package main 26 27 func testASM() 28 29 func main() { 30 testASM() 31 } 32 ` 33 34 func objdumpOutput(t *testing.T) []byte { 35 cwd, err := os.Getwd() 36 if err != nil { 37 t.Fatal(err) 38 } 39 tmpdir, err := ioutil.TempDir("", "19518") 40 if err != nil { 41 t.Fatal(err) 42 } 43 defer os.RemoveAll(tmpdir) 44 tmpfile, err := os.Create(filepath.Join(tmpdir, "input.s")) 45 if err != nil { 46 t.Fatal(err) 47 } 48 defer tmpfile.Close() 49 _, err = tmpfile.WriteString(asmData) 50 if err != nil { 51 t.Fatal(err) 52 } 53 tmpfile2, err := os.Create(filepath.Join(tmpdir, "input.go")) 54 if err != nil { 55 t.Fatal(err) 56 } 57 defer tmpfile2.Close() 58 _, err = tmpfile2.WriteString(goData) 59 if err != nil { 60 t.Fatal(err) 61 } 62 err = os.Chdir(tmpdir) 63 if err != nil { 64 t.Fatal(err) 65 } 66 cmd := exec.Command( 67 testenv.GoToolPath(t), "build", "-o", 68 filepath.Join(tmpdir, "output")) 69 70 cmd.Env = append(os.Environ(), "GOARCH=amd64", "GOOS=linux") 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 objout, err := cmd2.CombinedOutput() 81 if err != nil { 82 t.Fatalf("error %s output %s", err, objout) 83 } 84 err = os.Chdir(cwd) 85 if err != nil { 86 t.Fatal(err) 87 } 88 return objout 89 } 90 91 func TestVexPCrelative(t *testing.T) { 92 testenv.MustHaveGoBuild(t) 93 objout := objdumpOutput(t) 94 data := bytes.Split(objout, []byte("\n")) 95 for idx := len(data) - 1; idx >= 0; idx-- { 96 // OBJDUMP doesn't know about VMOVDQU, 97 // so instead of checking that it was assembled correctly, 98 // check that RET wasn't overwritten. 99 if bytes.Index(data[idx], []byte("RET")) != -1 { 100 return 101 } 102 } 103 t.Fatal("RET was overwritten") 104 }