github.com/JimmyHuang454/JLS-go@v0.0.0-20230831150107-90d536585ba0/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 importcfgfile := filepath.Join(tmpdir, "hello.importcfg") 46 testenv.WriteImportcfg(t, importcfgfile, nil) 47 48 // parse assembly code for symabi. 49 cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-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 = exec.Command(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 }