github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/src/cmd/internal/rsc.io/x86/x86asm/objdump_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  	"strings"
    10  	"testing"
    11  )
    12  
    13  func TestObjdump32Manual(t *testing.T)   { testObjdump32(t, hexCases(t, objdumpManualTests)) }
    14  func TestObjdump32Testdata(t *testing.T) { testObjdump32(t, concat(basicPrefixes, testdataCases(t))) }
    15  func TestObjdump32ModRM(t *testing.T)    { testObjdump32(t, concat(basicPrefixes, enumModRM)) }
    16  func TestObjdump32OneByte(t *testing.T)  { testBasic(t, testObjdump32) }
    17  func TestObjdump320F(t *testing.T)       { testBasic(t, testObjdump32, 0x0F) }
    18  func TestObjdump320F38(t *testing.T)     { testBasic(t, testObjdump32, 0x0F, 0x38) }
    19  func TestObjdump320F3A(t *testing.T)     { testBasic(t, testObjdump32, 0x0F, 0x3A) }
    20  func TestObjdump32Prefix(t *testing.T)   { testPrefix(t, testObjdump32) }
    21  
    22  func TestObjdump64Manual(t *testing.T)   { testObjdump64(t, hexCases(t, objdumpManualTests)) }
    23  func TestObjdump64Testdata(t *testing.T) { testObjdump64(t, concat(basicPrefixes, testdataCases(t))) }
    24  func TestObjdump64ModRM(t *testing.T)    { testObjdump64(t, concat(basicPrefixes, enumModRM)) }
    25  func TestObjdump64OneByte(t *testing.T)  { testBasic(t, testObjdump64) }
    26  func TestObjdump640F(t *testing.T)       { testBasic(t, testObjdump64, 0x0F) }
    27  func TestObjdump640F38(t *testing.T)     { testBasic(t, testObjdump64, 0x0F, 0x38) }
    28  func TestObjdump640F3A(t *testing.T)     { testBasic(t, testObjdump64, 0x0F, 0x3A) }
    29  func TestObjdump64Prefix(t *testing.T)   { testPrefix(t, testObjdump64) }
    30  
    31  func TestObjdump64REXTestdata(t *testing.T) {
    32  	testObjdump64(t, filter(concat3(basicPrefixes, rexPrefixes, testdataCases(t)), isValidREX))
    33  }
    34  func TestObjdump64REXModRM(t *testing.T) {
    35  	testObjdump64(t, concat3(basicPrefixes, rexPrefixes, enumModRM))
    36  }
    37  func TestObjdump64REXOneByte(t *testing.T) { testBasicREX(t, testObjdump64) }
    38  func TestObjdump64REX0F(t *testing.T)      { testBasicREX(t, testObjdump64, 0x0F) }
    39  func TestObjdump64REX0F38(t *testing.T)    { testBasicREX(t, testObjdump64, 0x0F, 0x38) }
    40  func TestObjdump64REX0F3A(t *testing.T)    { testBasicREX(t, testObjdump64, 0x0F, 0x3A) }
    41  func TestObjdump64REXPrefix(t *testing.T)  { testPrefixREX(t, testObjdump64) }
    42  
    43  // objdumpManualTests holds test cases that will be run by TestObjdumpManual.
    44  // If you are debugging a few cases that turned up in a longer run, it can be useful
    45  // to list them here and then use -run=ObjdumpManual, particularly with tracing enabled.
    46  var objdumpManualTests = `
    47  F390
    48  `
    49  
    50  // allowedMismatchObjdump reports whether the mismatch between text and dec
    51  // should be allowed by the test.
    52  func allowedMismatchObjdump(text string, size int, inst *Inst, dec ExtInst) bool {
    53  	if size == 15 && dec.nenc == 15 && contains(text, "truncated") && contains(dec.text, "(bad)") {
    54  		return true
    55  	}
    56  
    57  	if i := strings.LastIndex(dec.text, " "); isPrefix(dec.text[i+1:]) && size == 1 && isPrefix(text) {
    58  		return true
    59  	}
    60  
    61  	if size == dec.nenc && contains(dec.text, "movupd") && contains(dec.text, "data32") {
    62  		s := strings.Replace(dec.text, "data32 ", "", -1)
    63  		if text == s {
    64  			return true
    65  		}
    66  	}
    67  
    68  	// Simplify our invalid instruction text.
    69  	if text == "error: unrecognized instruction" {
    70  		text = "BAD"
    71  	}
    72  
    73  	// Invalid instructions for which libopcodes prints %? register.
    74  	// FF E8 11 22 33 44:
    75  	// Invalid instructions for which libopcodes prints "internal disassembler error".
    76  	// Invalid instructions for which libopcodes prints 8087 only (e.g., DB E0)
    77  	// or prints 287 only (e.g., DB E4).
    78  	if contains(dec.text, "%?", "<internal disassembler error>", "(8087 only)", "(287 only)") {
    79  		dec.text = "(bad)"
    80  	}
    81  
    82  	// 0F 19 11, 0F 1C 11, 0F 1D 11, 0F 1E 11, 0F 1F 11: libopcodes says nop,
    83  	// but the Intel manuals say that the only NOP there is 0F 1F /0.
    84  	// Perhaps libopcodes is reporting an older encoding.
    85  	i := bytes.IndexByte(dec.enc[:], 0x0F)
    86  	if contains(dec.text, "nop") && i >= 0 && i+2 < len(dec.enc) && dec.enc[i+1]&^7 == 0x18 && (dec.enc[i+1] != 0x1F || (dec.enc[i+2]>>3)&7 != 0) {
    87  		dec.text = "(bad)"
    88  	}
    89  
    90  	// Any invalid instruction.
    91  	if text == "BAD" && contains(dec.text, "(bad)") {
    92  		return true
    93  	}
    94  
    95  	// Instructions libopcodes knows but we do not (e.g., 0F 19 11).
    96  	if (text == "BAD" || size == 1 && isPrefix(text)) && hasPrefix(dec.text, unsupported...) {
    97  		return true
    98  	}
    99  
   100  	// Instructions we know but libopcodes does not (e.g., 0F D0 11).
   101  	if (contains(dec.text, "(bad)") || dec.nenc == 1 && isPrefix(dec.text)) && hasPrefix(text, libopcodesUnsupported...) {
   102  		return true
   103  	}
   104  
   105  	// Libopcodes rejects F2 90 as NOP. Not sure why.
   106  	if (contains(dec.text, "(bad)") || dec.nenc == 1 && isPrefix(dec.text)) && inst.Opcode>>24 == 0x90 && countPrefix(inst, 0xF2) > 0 {
   107  		return true
   108  	}
   109  
   110  	// 0F 20 11, 0F 21 11, 0F 22 11, 0F 23 11, 0F 24 11:
   111  	// Moves into and out of some control registers seem to be unsupported by libopcodes.
   112  	// TODO(rsc): Are they invalid somehow?
   113  	if (contains(dec.text, "(bad)") || dec.nenc == 1 && isPrefix(dec.text)) && contains(text, "%cr", "%db", "%tr") {
   114  		return true
   115  	}
   116  
   117  	if contains(dec.text, "fwait") && dec.nenc == 1 && dec.enc[0] != 0x9B {
   118  		return true
   119  	}
   120  
   121  	// 9B D9 11: libopcodes reports FSTSW instead of FWAIT + FNSTSW.
   122  	// This is correct in that FSTSW is a pseudo-op for the pair, but it really
   123  	// is a pair of instructions: execution can stop between them.
   124  	// Our decoder chooses to separate them.
   125  	if (text == "fwait" || strings.HasSuffix(text, " fwait")) && dec.nenc >= len(strings.Fields(text)) && dec.enc[len(strings.Fields(text))-1] == 0x9B {
   126  		return true
   127  	}
   128  
   129  	// 0F 18 77 11:
   130  	// Invalid instructions for which libopcodes prints "nop/reserved".
   131  	// Perhaps libopcodes is reporting an older encoding.
   132  	if text == "BAD" && contains(dec.text, "nop/reserved") {
   133  		return true
   134  	}
   135  
   136  	// 0F C7 B0 11 22 33 44: libopcodes says vmptrld 0x44332211(%eax); we say rdrand %eax.
   137  	// TODO(rsc): Fix, since we are probably wrong, but we don't have vmptrld in the manual.
   138  	if contains(text, "rdrand") && contains(dec.text, "vmptrld", "vmxon", "vmclear") {
   139  		return true
   140  	}
   141  
   142  	// DD C8: libopcodes says FNOP but the Intel manual is clear FNOP is only D9 D0.
   143  	// Perhaps libopcodes is reporting an older encoding.
   144  	if text == "BAD" && contains(dec.text, "fnop") && (dec.enc[0] != 0xD9 || dec.enc[1] != 0xD0) {
   145  		return true
   146  	}
   147  
   148  	// 66 90: libopcodes says xchg %ax,%ax; we say 'data16 nop'.
   149  	// The 16-bit swap will preserve the high bits of the register,
   150  	// so they are the same.
   151  	if contains(text, "nop") && contains(dec.text, "xchg %ax,%ax") {
   152  		return true
   153  	}
   154  
   155  	// If there are multiple prefixes, allow libopcodes to use an alternate name.
   156  	if size == 1 && dec.nenc == 1 && prefixByte[text] > 0 && prefixByte[text] == prefixByte[dec.text] {
   157  		return true
   158  	}
   159  
   160  	// 26 9B: libopcodes reports "fwait"/1, ignoring segment prefix.
   161  	// https://sourceware.org/bugzilla/show_bug.cgi?id=16891
   162  	// F0 82: Decode="lock"/1 but libopcodes="lock (bad)"/2.
   163  	if size == 1 && dec.nenc >= 1 && prefixByte[text] == dec.enc[0] && contains(dec.text, "(bad)", "fwait", "fnop") {
   164  		return true
   165  	}
   166  
   167  	// libopcodes interprets 660f801122 as taking a rel16 but
   168  	// truncating the address at 16 bits. Not sure what is correct.
   169  	if contains(text, ".+0x2211", ".+0x11") && contains(dec.text, " .-") {
   170  		return true
   171  	}
   172  
   173  	// 66 F3 0F D6 C5, 66 F2 0F D6 C0: libopcodes reports use of XMM register instead of MMX register,
   174  	// but only when the instruction has a 66 prefix. Maybe they know something we don't.
   175  	if countPrefix(inst, 0x66) > 0 && contains(dec.text, "movdq2q", "movq2dq") && !contains(dec.text, "%mm") {
   176  		return true
   177  	}
   178  
   179  	// 0F 01 F8, 0F 05, 0F 07: these are 64-bit instructions but libopcodes accepts them.
   180  	if (text == "BAD" || size == 1 && isPrefix(text)) && contains(dec.text, "swapgs", "syscall", "sysret", "rdfsbase", "rdgsbase", "wrfsbase", "wrgsbase") {
   181  		return true
   182  	}
   183  
   184  	return false
   185  }
   186  
   187  // Instructions known to libopcodes (or xed) but not to us.
   188  // Most of these come from supplementary manuals of one form or another.
   189  var unsupported = strings.Fields(`
   190  	bndc
   191  	bndl
   192  	bndm
   193  	bnds
   194  	clac
   195  	clgi
   196  	femms
   197  	fldln
   198  	fldz
   199  	getsec
   200  	invlpga
   201  	kmov
   202  	montmul
   203  	pavg
   204  	pf2i
   205  	pfacc
   206  	pfadd
   207  	pfcmp
   208  	pfmax
   209  	pfmin
   210  	pfmul
   211  	pfna
   212  	pfpnac
   213  	pfrc
   214  	pfrs
   215  	pfsub
   216  	phadd
   217  	phsub
   218  	pi2f
   219  	pmulhr
   220  	prefetch
   221  	pswap
   222  	ptest
   223  	rdseed
   224  	sha1
   225  	sha256
   226  	skinit
   227  	stac
   228  	stgi
   229  	vadd
   230  	vand
   231  	vcmp
   232  	vcomis
   233  	vcvt
   234  	vcvt
   235  	vdiv
   236  	vhadd
   237  	vhsub
   238  	vld
   239  	vmax
   240  	vmcall
   241  	vmfunc
   242  	vmin
   243  	vmlaunch
   244  	vmload
   245  	vmmcall
   246  	vmov
   247  	vmov
   248  	vmov
   249  	vmptrld
   250  	vmptrst
   251  	vmread
   252  	vmresume
   253  	vmrun
   254  	vmsave
   255  	vmul
   256  	vmwrite
   257  	vmxoff
   258  	vor
   259  	vpack
   260  	vpadd
   261  	vpand
   262  	vpavg
   263  	vpcmp
   264  	vpcmp
   265  	vpins
   266  	vpmadd
   267  	vpmax
   268  	vpmin
   269  	vpmul
   270  	vpmul
   271  	vpor
   272  	vpsad
   273  	vpshuf
   274  	vpsll
   275  	vpsra
   276  	vpsrad
   277  	vpsrl
   278  	vpsub
   279  	vpunp
   280  	vpxor
   281  	vrcp
   282  	vrsqrt
   283  	vshuf
   284  	vsqrt
   285  	vsub
   286  	vucomis
   287  	vunp
   288  	vxor
   289  	vzero
   290  	xcrypt
   291  	xsha1
   292  	xsha256
   293  	xstore-rng
   294  	insertq
   295  	extrq
   296  	vmclear
   297  	invvpid
   298  	adox
   299  	vmxon
   300  	invept
   301  	adcx
   302  	vmclear
   303  	prefetchwt1
   304  	enclu
   305  	encls
   306  	salc
   307  	fstpnce
   308  	fdisi8087_nop
   309  	fsetpm287_nop
   310  	feni8087_nop
   311  	syscall
   312  	sysret
   313  `)
   314  
   315  // Instructions known to us but not to libopcodes (at least in binutils 2.24).
   316  var libopcodesUnsupported = strings.Fields(`
   317  	addsubps
   318  	aes
   319  	blend
   320  	cvttpd2dq
   321  	dpp
   322  	extract
   323  	haddps
   324  	hsubps
   325  	insert
   326  	invpcid
   327  	lddqu
   328  	movmsk
   329  	movnt
   330  	movq2dq
   331  	mps
   332  	pack
   333  	pblend
   334  	pclmul
   335  	pcmp
   336  	pext
   337  	phmin
   338  	pins
   339  	pmax
   340  	pmin
   341  	pmov
   342  	pmovmsk
   343  	pmul
   344  	popcnt
   345  	pslld
   346  	psllq
   347  	psllw
   348  	psrad
   349  	psraw
   350  	psrl
   351  	ptest
   352  	punpck
   353  	round
   354  	xrstor
   355  	xsavec
   356  	xsaves
   357  	comis
   358  	ucomis
   359  	movhps
   360  	movntps
   361  	rsqrt
   362  	rcpp
   363  	puncpck
   364  	bsf
   365  	movq2dq
   366  	cvttpd2dq
   367  	movq
   368  	hsubpd
   369  	movdqa
   370  	movhpd
   371  	addsubpd
   372  	movd
   373  	haddpd
   374  	cvtps2dq
   375  	bsr
   376  	cvtdq2ps
   377  	rdrand
   378  	maskmov
   379  	movq2dq
   380  	movlhps
   381  	movbe
   382  	movlpd
   383  `)