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