github.com/Filosottile/go@v0.0.0-20170906193555-dbed9972d994/src/cmd/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  	"strings"
    15  	"testing"
    16  )
    17  
    18  const asmData = `
    19  GLOBL zeros<>(SB),8,$64
    20  TEXT ·testASM(SB),4,$0
    21  VMOVDQU zeros<>(SB), Y8 // PC relative relocation is off by 1, for Y8-15
    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) []byte {
    36  	cwd, err := os.Getwd()
    37  	if err != nil {
    38  		t.Fatal(err)
    39  	}
    40  	tmpdir, err := ioutil.TempDir("", "19518")
    41  	if err != nil {
    42  		t.Fatal(err)
    43  	}
    44  	defer os.RemoveAll(tmpdir)
    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(asmData)
    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  	err = os.Chdir(tmpdir)
    64  	if err != nil {
    65  		t.Fatal(err)
    66  	}
    67  	cmd := exec.Command(
    68  		testenv.GoToolPath(t), "build", "-o",
    69  		filepath.Join(tmpdir, "output"))
    70  
    71  	var env []string
    72  	for _, v := range os.Environ() {
    73  		if !strings.HasPrefix(v, "GOARCH=") {
    74  			env = append(env, v)
    75  		}
    76  	}
    77  	cmd.Env = append(env, "GOARCH=amd64")
    78  	out, err := cmd.CombinedOutput()
    79  	if err != nil {
    80  		t.Fatalf("error %s output %s", err, out)
    81  	}
    82  	cmd2 := exec.Command(
    83  		testenv.GoToolPath(t), "tool", "objdump", "-s", "testASM",
    84  		filepath.Join(tmpdir, "output"))
    85  	cmd2.Env = cmd.Env
    86  	objout, err := cmd2.CombinedOutput()
    87  	if err != nil {
    88  		t.Fatalf("error %s output %s", err, objout)
    89  	}
    90  	err = os.Chdir(cwd)
    91  	if err != nil {
    92  		t.Fatal(err)
    93  	}
    94  	return objout
    95  }
    96  
    97  func TestVexPCrelative(t *testing.T) {
    98  	testenv.MustHaveGoBuild(t)
    99  	objout := objdumpOutput(t)
   100  	data := bytes.Split(objout, []byte("\n"))
   101  	for idx := len(data) - 1; idx >= 0; idx-- {
   102  		// OBJDUMP doesn't know about VMOVDQU,
   103  		// so instead of checking that it was assembled correctly,
   104  		// check that RET wasn't overwritten.
   105  		if bytes.Index(data[idx], []byte("RET")) != -1 {
   106  			return
   107  		}
   108  	}
   109  	t.Fatal("RET was overwritten")
   110  }