...

Source file src/golang.org/x/arch/x86/x86asm/plan9ext_test.go

Documentation: golang.org/x/arch/x86/x86asm

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

View as plain text