github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/src/cmd/internal/rsc.io/x86/x86asm/plan9ext_test.go (about)

     1  // Copyright 2014 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 x86asm
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io"
    11  	"log"
    12  	"os"
    13  	"strconv"
    14  	"testing"
    15  )
    16  
    17  const plan9Path = "testdata/libmach8db"
    18  
    19  func testPlan9Arch(t *testing.T, arch int, generate func(func([]byte))) {
    20  	if testing.Short() {
    21  		t.Skip("skipping libmach test in short mode")
    22  	}
    23  
    24  	if _, err := os.Stat(plan9Path); err != nil {
    25  		t.Fatal(err)
    26  	}
    27  
    28  	testExtDis(t, "plan9", arch, plan9, generate, allowedMismatchPlan9)
    29  }
    30  
    31  func testPlan932(t *testing.T, generate func(func([]byte))) {
    32  	testPlan9Arch(t, 32, generate)
    33  }
    34  
    35  func testPlan964(t *testing.T, generate func(func([]byte))) {
    36  	testPlan9Arch(t, 64, generate)
    37  }
    38  
    39  func plan9(ext *ExtDis) error {
    40  	flag := "-8"
    41  	if ext.Arch == 64 {
    42  		flag = "-6"
    43  	}
    44  	b, err := ext.Run(plan9Path, flag, ext.File.Name())
    45  	if err != nil {
    46  		return err
    47  	}
    48  
    49  	nmatch := 0
    50  	next := uint32(start)
    51  	var (
    52  		addr   uint32
    53  		encbuf [32]byte
    54  		enc    []byte
    55  		text   string
    56  	)
    57  
    58  	for {
    59  		line, err := b.ReadSlice('\n')
    60  		if err != nil {
    61  			if err == io.EOF {
    62  				break
    63  			}
    64  			return fmt.Errorf("reading libmach8db output: %v", err)
    65  		}
    66  		if debug {
    67  			os.Stdout.Write(line)
    68  		}
    69  		nmatch++
    70  		addr, enc, text = parseLinePlan9(line, encbuf[:0])
    71  		if addr > next {
    72  			return fmt.Errorf("address out of sync expected <= %#x at %q in:\n%s", next, line, line)
    73  		}
    74  		if addr < next {
    75  			continue
    76  		}
    77  		if m := pcrelw.FindStringSubmatch(text); m != nil {
    78  			targ, _ := strconv.ParseUint(m[2], 16, 64)
    79  			text = fmt.Sprintf("%s .%+#x", m[1], int16(uint32(targ)-uint32(uint16(addr))-uint32(len(enc))))
    80  		}
    81  		if m := pcrel.FindStringSubmatch(text); m != nil {
    82  			targ, _ := strconv.ParseUint(m[2], 16, 64)
    83  			text = fmt.Sprintf("%s .%+#x", m[1], int32(uint32(targ)-addr-uint32(len(enc))))
    84  		}
    85  		ext.Dec <- ExtInst{addr, encbuf, len(enc), text}
    86  		encbuf = [32]byte{}
    87  		enc = nil
    88  		next += 32
    89  	}
    90  	if next != start+uint32(ext.Size) {
    91  		return fmt.Errorf("not enough results found [%d %d]", next, start+ext.Size)
    92  	}
    93  	if err := ext.Wait(); err != nil {
    94  		return fmt.Errorf("exec: %v", err)
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  func parseLinePlan9(line []byte, encstart []byte) (addr uint32, enc []byte, text string) {
   101  	i := bytes.IndexByte(line, ' ')
   102  	if i < 0 || line[0] != '0' || line[1] != 'x' {
   103  		log.Fatalf("cannot parse disassembly: %q", line)
   104  	}
   105  	j := bytes.IndexByte(line[i+1:], ' ')
   106  	if j < 0 {
   107  		log.Fatalf("cannot parse disassembly: %q", line)
   108  	}
   109  	j += i + 1
   110  	x, err := strconv.ParseUint(string(trimSpace(line[2:i])), 16, 32)
   111  	if err != nil {
   112  		log.Fatalf("cannot parse disassembly: %q", line)
   113  	}
   114  	addr = uint32(x)
   115  	enc, ok := parseHex(line[i+1:j], encstart)
   116  	if !ok {
   117  		log.Fatalf("cannot parse disassembly: %q", line)
   118  	}
   119  	return addr, enc, string(fixSpace(line[j+1:]))
   120  }