Source file src/internal/abi/abi_test.go

     1  // Copyright 2021 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 abi_test
     6  
     7  import (
     8  	"internal/abi"
     9  	"internal/testenv"
    10  	"os/exec"
    11  	"path/filepath"
    12  	"strings"
    13  	"testing"
    14  )
    15  
    16  func TestFuncPC(t *testing.T) {
    17  	// Test that FuncPC* can get correct function PC.
    18  	pcFromAsm := abi.FuncPCTestFnAddr
    19  
    20  	// Test FuncPC for locally defined function
    21  	pcFromGo := abi.FuncPCTest()
    22  	if pcFromGo != pcFromAsm {
    23  		t.Errorf("FuncPC returns wrong PC, want %x, got %x", pcFromAsm, pcFromGo)
    24  	}
    25  
    26  	// Test FuncPC for imported function
    27  	pcFromGo = abi.FuncPCABI0(abi.FuncPCTestFn)
    28  	if pcFromGo != pcFromAsm {
    29  		t.Errorf("FuncPC returns wrong PC, want %x, got %x", pcFromAsm, pcFromGo)
    30  	}
    31  }
    32  
    33  func TestFuncPCCompileError(t *testing.T) {
    34  	// Test that FuncPC* on a function of a mismatched ABI is rejected.
    35  	testenv.MustHaveGoBuild(t)
    36  
    37  	// We want to test internal package, which we cannot normally import.
    38  	// Run the assembler and compiler manually.
    39  	tmpdir := t.TempDir()
    40  	asmSrc := filepath.Join("testdata", "x.s")
    41  	goSrc := filepath.Join("testdata", "x.go")
    42  	symabi := filepath.Join(tmpdir, "symabi")
    43  	obj := filepath.Join(tmpdir, "x.o")
    44  
    45  	// parse assembly code for symabi.
    46  	cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-gensymabis", "-o", symabi, asmSrc)
    47  	out, err := cmd.CombinedOutput()
    48  	if err != nil {
    49  		t.Fatalf("go tool asm -gensymabis failed: %v\n%s", err, out)
    50  	}
    51  
    52  	// compile go code.
    53  	cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-symabis", symabi, "-o", obj, goSrc)
    54  	out, err = cmd.CombinedOutput()
    55  	if err == nil {
    56  		t.Fatalf("go tool compile did not fail")
    57  	}
    58  
    59  	// Expect errors in line 17, 18, 20, no errors on other lines.
    60  	want := []string{"x.go:17", "x.go:18", "x.go:20"}
    61  	got := strings.Split(string(out), "\n")
    62  	if got[len(got)-1] == "" {
    63  		got = got[:len(got)-1] // remove last empty line
    64  	}
    65  	for i, s := range got {
    66  		if !strings.Contains(s, want[i]) {
    67  			t.Errorf("did not error on line %s", want[i])
    68  		}
    69  	}
    70  	if len(got) != len(want) {
    71  		t.Errorf("unexpected number of errors, want %d, got %d", len(want), len(got))
    72  	}
    73  	if t.Failed() {
    74  		t.Logf("output:\n%s", string(out))
    75  	}
    76  }
    77  

View as plain text