github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/link/elf_test.go (about)

     1  // Copyright 2019 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  // +build dragonfly freebsd linux netbsd openbsd
     6  
     7  package main
     8  
     9  import (
    10  	"internal/testenv"
    11  	"io/ioutil"
    12  	"os"
    13  	"os/exec"
    14  	"path/filepath"
    15  	"strings"
    16  	"testing"
    17  )
    18  
    19  var asmSource = `
    20  	.section .text1,"ax"
    21  s1:
    22  	.byte 0
    23  	.section .text2,"ax"
    24  s2:
    25  	.byte 0
    26  `
    27  
    28  var goSource = `
    29  package main
    30  func main() {}
    31  `
    32  
    33  // The linker used to crash if an ELF input file had multiple text sections
    34  // with the same name.
    35  func TestSectionsWithSameName(t *testing.T) {
    36  	testenv.MustHaveGoBuild(t)
    37  	testenv.MustHaveCGO(t)
    38  	t.Parallel()
    39  
    40  	objcopy, err := exec.LookPath("objcopy")
    41  	if err != nil {
    42  		t.Skipf("can't find objcopy: %v", err)
    43  	}
    44  
    45  	dir, err := ioutil.TempDir("", "go-link-TestSectionsWithSameName")
    46  	if err != nil {
    47  		t.Fatal(err)
    48  	}
    49  	defer os.RemoveAll(dir)
    50  
    51  	gopath := filepath.Join(dir, "GOPATH")
    52  	env := append(os.Environ(), "GOPATH="+gopath)
    53  
    54  	if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte("module elf_test\n"), 0666); err != nil {
    55  		t.Fatal(err)
    56  	}
    57  
    58  	asmFile := filepath.Join(dir, "x.s")
    59  	if err := ioutil.WriteFile(asmFile, []byte(asmSource), 0444); err != nil {
    60  		t.Fatal(err)
    61  	}
    62  
    63  	goTool := testenv.GoToolPath(t)
    64  	cmd := exec.Command(goTool, "env", "CC")
    65  	cmd.Env = env
    66  	ccb, err := cmd.Output()
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  	cc := strings.TrimSpace(string(ccb))
    71  
    72  	cmd = exec.Command(goTool, "env", "GOGCCFLAGS")
    73  	cmd.Env = env
    74  	cflagsb, err := cmd.Output()
    75  	if err != nil {
    76  		t.Fatal(err)
    77  	}
    78  	cflags := strings.Fields(string(cflagsb))
    79  
    80  	asmObj := filepath.Join(dir, "x.o")
    81  	t.Logf("%s %v -c -o %s %s", cc, cflags, asmObj, asmFile)
    82  	if out, err := exec.Command(cc, append(cflags, "-c", "-o", asmObj, asmFile)...).CombinedOutput(); err != nil {
    83  		t.Logf("%s", out)
    84  		t.Fatal(err)
    85  	}
    86  
    87  	asm2Obj := filepath.Join(dir, "x2.syso")
    88  	t.Logf("%s --rename-section .text2=.text1 %s %s", objcopy, asmObj, asm2Obj)
    89  	if out, err := exec.Command(objcopy, "--rename-section", ".text2=.text1", asmObj, asm2Obj).CombinedOutput(); err != nil {
    90  		t.Logf("%s", out)
    91  		t.Fatal(err)
    92  	}
    93  
    94  	for _, s := range []string{asmFile, asmObj} {
    95  		if err := os.Remove(s); err != nil {
    96  			t.Fatal(err)
    97  		}
    98  	}
    99  
   100  	goFile := filepath.Join(dir, "main.go")
   101  	if err := ioutil.WriteFile(goFile, []byte(goSource), 0444); err != nil {
   102  		t.Fatal(err)
   103  	}
   104  
   105  	cmd = exec.Command(goTool, "build")
   106  	cmd.Dir = dir
   107  	cmd.Env = env
   108  	t.Logf("%s build", goTool)
   109  	if out, err := cmd.CombinedOutput(); err != nil {
   110  		t.Logf("%s", out)
   111  		t.Fatal(err)
   112  	}
   113  }