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

View as plain text