github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/internal/abi/abi_test.go (about) 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 }