Source file src/cmd/link/internal/ld/elf_test.go

     1  //go:build cgo
     2  // +build cgo
     3  
     4  // Copyright 2019 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  package ld
     9  
    10  import (
    11  	"debug/elf"
    12  	"internal/testenv"
    13  	"io/ioutil"
    14  	"os"
    15  	"os/exec"
    16  	"path/filepath"
    17  	"runtime"
    18  	"strings"
    19  	"testing"
    20  )
    21  
    22  func TestDynSymShInfo(t *testing.T) {
    23  	t.Parallel()
    24  	testenv.MustHaveGoBuild(t)
    25  	dir := t.TempDir()
    26  
    27  	const prog = `
    28  package main
    29  
    30  import "net"
    31  
    32  func main() {
    33  	net.Dial("", "")
    34  }
    35  `
    36  	src := filepath.Join(dir, "issue33358.go")
    37  	if err := ioutil.WriteFile(src, []byte(prog), 0666); err != nil {
    38  		t.Fatal(err)
    39  	}
    40  
    41  	binFile := filepath.Join(dir, "issue33358")
    42  	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", binFile, src)
    43  	if out, err := cmd.CombinedOutput(); err != nil {
    44  		t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
    45  	}
    46  
    47  	fi, err := os.Open(binFile)
    48  	if err != nil {
    49  		t.Fatalf("failed to open built file: %v", err)
    50  	}
    51  	defer fi.Close()
    52  
    53  	elfFile, err := elf.NewFile(fi)
    54  	if err != nil {
    55  		t.Skip("The system may not support ELF, skipped.")
    56  	}
    57  
    58  	section := elfFile.Section(".dynsym")
    59  	if section == nil {
    60  		t.Fatal("no dynsym")
    61  	}
    62  
    63  	symbols, err := elfFile.DynamicSymbols()
    64  	if err != nil {
    65  		t.Fatalf("failed to get dynamic symbols: %v", err)
    66  	}
    67  
    68  	var numLocalSymbols uint32
    69  	for i, s := range symbols {
    70  		if elf.ST_BIND(s.Info) != elf.STB_LOCAL {
    71  			numLocalSymbols = uint32(i + 1)
    72  			break
    73  		}
    74  	}
    75  
    76  	if section.Info != numLocalSymbols {
    77  		t.Fatalf("Unexpected sh info, want greater than 0, got: %d", section.Info)
    78  	}
    79  }
    80  
    81  func TestNoDuplicateNeededEntries(t *testing.T) {
    82  	testenv.MustHaveGoBuild(t)
    83  	testenv.MustHaveCGO(t)
    84  
    85  	// run this test on just a small set of platforms (no need to test it
    86  	// across the board given the nature of the test).
    87  	pair := runtime.GOOS + "-" + runtime.GOARCH
    88  	switch pair {
    89  	case "linux-amd64", "freebsd-amd64", "openbsd-amd64":
    90  	default:
    91  		t.Skip("no need for test on " + pair)
    92  	}
    93  
    94  	t.Parallel()
    95  
    96  	dir := t.TempDir()
    97  
    98  	wd, err := os.Getwd()
    99  	if err != nil {
   100  		t.Fatalf("Failed to get working directory: %v", err)
   101  	}
   102  
   103  	path := filepath.Join(dir, "x")
   104  	argv := []string{"build", "-o", path, filepath.Join(wd, "testdata", "issue39256")}
   105  	out, err := exec.Command(testenv.GoToolPath(t), argv...).CombinedOutput()
   106  	if err != nil {
   107  		t.Fatalf("Build failure: %s\n%s\n", err, string(out))
   108  	}
   109  
   110  	f, err := elf.Open(path)
   111  	if err != nil {
   112  		t.Fatalf("Failed to open ELF file: %v", err)
   113  	}
   114  	libs, err := f.ImportedLibraries()
   115  	if err != nil {
   116  		t.Fatalf("Failed to read imported libraries: %v", err)
   117  	}
   118  
   119  	var count int
   120  	for _, lib := range libs {
   121  		if lib == "libc.so" || strings.HasPrefix(lib, "libc.so.") {
   122  			count++
   123  		}
   124  	}
   125  
   126  	if got, want := count, 1; got != want {
   127  		t.Errorf("Got %d entries for `libc.so`, want %d", got, want)
   128  	}
   129  }
   130  

View as plain text