github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/cmd/link/internal/ld/dwarf_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 ld
     6  
     7  import (
     8  	objfilepkg "cmd/internal/objfile" // renamed to avoid conflict with objfile function
     9  	"debug/dwarf"
    10  	"internal/testenv"
    11  	"io/ioutil"
    12  	"os"
    13  	"os/exec"
    14  	"path/filepath"
    15  	"runtime"
    16  	"testing"
    17  )
    18  
    19  func TestRuntimeTypeDIEs(t *testing.T) {
    20  	testenv.MustHaveGoBuild(t)
    21  
    22  	if runtime.GOOS == "plan9" {
    23  		t.Skip("skipping on plan9; no DWARF symbol table in executables")
    24  	}
    25  
    26  	dir, err := ioutil.TempDir("", "TestRuntimeTypeDIEs")
    27  	if err != nil {
    28  		t.Fatalf("could not create directory: %v", err)
    29  	}
    30  	defer os.RemoveAll(dir)
    31  
    32  	f := gobuild(t, dir, `package main; func main() { }`)
    33  	defer f.Close()
    34  
    35  	dwarf, err := f.DWARF()
    36  	if err != nil {
    37  		t.Fatalf("error reading DWARF: %v", err)
    38  	}
    39  
    40  	want := map[string]bool{
    41  		"runtime._type":         true,
    42  		"runtime.arraytype":     true,
    43  		"runtime.chantype":      true,
    44  		"runtime.functype":      true,
    45  		"runtime.maptype":       true,
    46  		"runtime.ptrtype":       true,
    47  		"runtime.slicetype":     true,
    48  		"runtime.structtype":    true,
    49  		"runtime.interfacetype": true,
    50  		"runtime.itab":          true,
    51  		"runtime.imethod":       true,
    52  	}
    53  
    54  	found := findTypes(t, dwarf, want)
    55  	if len(found) != len(want) {
    56  		t.Errorf("found %v, want %v", found, want)
    57  	}
    58  }
    59  
    60  func findTypes(t *testing.T, dw *dwarf.Data, want map[string]bool) (found map[string]bool) {
    61  	found = make(map[string]bool)
    62  	rdr := dw.Reader()
    63  	for entry, err := rdr.Next(); entry != nil; entry, err = rdr.Next() {
    64  		if err != nil {
    65  			t.Fatalf("error reading DWARF: %v", err)
    66  		}
    67  		switch entry.Tag {
    68  		case dwarf.TagTypedef:
    69  			if name, ok := entry.Val(dwarf.AttrName).(string); ok && want[name] {
    70  				found[name] = true
    71  			}
    72  		}
    73  	}
    74  	return
    75  }
    76  
    77  func gobuild(t *testing.T, dir string, testfile string) *objfilepkg.File {
    78  	src := filepath.Join(dir, "test.go")
    79  	dst := filepath.Join(dir, "out")
    80  
    81  	if err := ioutil.WriteFile(src, []byte(testfile), 0666); err != nil {
    82  		t.Fatal(err)
    83  	}
    84  
    85  	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src)
    86  	if b, err := cmd.CombinedOutput(); err != nil {
    87  		t.Logf("build: %s\n", b)
    88  		t.Fatalf("build error: %v", err)
    89  	}
    90  
    91  	f, err := objfilepkg.Open(dst)
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  	return f
    96  }