...

Source file src/golang.org/x/arch/arm64/arm64asm/objdump_test.go

Documentation: golang.org/x/arch/arm64/arm64asm

     1  // Copyright 2017 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 arm64asm
     6  
     7  import (
     8  	"strings"
     9  	"testing"
    10  )
    11  
    12  func TestObjdumpARM64TestDecodeGNUSyntaxdata(t *testing.T) {
    13  	testObjdumpARM64(t, testdataCases(t, "gnu"))
    14  }
    15  func TestObjdumpARM64TestDecodeGoSyntaxdata(t *testing.T) {
    16  	testObjdumpARM64(t, testdataCases(t, "plan9"))
    17  }
    18  func TestObjdumpARM64Manual(t *testing.T) { testObjdumpARM64(t, hexCases(t, objdumpManualTests)) }
    19  func TestObjdumpARM64Cond(t *testing.T)   { testObjdumpARM64(t, condCases(t)) }
    20  func TestObjdumpARM64(t *testing.T)       { testObjdumpARM64(t, JSONCases(t)) }
    21  
    22  // objdumpManualTests holds test cases that will be run by TestObjdumpARMManual.
    23  // If you are debugging a few cases that turned up in a longer run, it can be useful
    24  // to list them here and then use -run=Manual, particularly with tracing enabled.
    25  // Note that these are byte sequences, so they must be reversed from the usual
    26  // word presentation.
    27  var objdumpManualTests = `
    28  bf2003d5
    29  9f2003d5
    30  7f2003d5
    31  5f2003d5
    32  3f2003d5
    33  1f2003d5
    34  df4d03d5
    35  ff4d03d5
    36  28d91b14
    37  da6cb530
    38  15e5e514
    39  ff4603d5
    40  df4803d5
    41  bf4100d5
    42  9f3f03d5
    43  9f3e03d5
    44  9f3d03d5
    45  9f3b03d5
    46  9f3a03d5
    47  9f3903d5
    48  9f3703d5
    49  9f3603d5
    50  9f3503d5
    51  9f3303d5
    52  9f3203d5
    53  9f3103d5
    54  ff4603d5
    55  df4803d5
    56  bf4100d5
    57  a3681b53
    58  47dc78d3
    59  0500a012
    60  0500e092
    61  0500a052
    62  0500a0d2
    63  cd5a206e
    64  cd5a202e
    65  743d050e
    66  743d0a0e
    67  743d0c0e
    68  743d084e
    69  `
    70  
    71  // allowedMismatchObjdump reports whether the mismatch between text and dec
    72  // should be allowed by the test.
    73  func allowedMismatchObjdump(text string, inst *Inst, dec ExtInst) bool {
    74  	// Skip unsupported instructions
    75  	if hasPrefix(dec.text, todo...) {
    76  		return true
    77  	}
    78  	// GNU objdump has incorrect alias conditions for following instructions
    79  	if inst.Enc&0x000003ff == 0x000003ff && hasPrefix(dec.text, "negs") && hasPrefix(text, "cmp") {
    80  		return true
    81  	}
    82  	// GNU objdump "NV" is equal to our "AL"
    83  	if strings.HasSuffix(dec.text, " nv") && strings.HasSuffix(text, " al") {
    84  		return true
    85  	}
    86  	if strings.HasPrefix(dec.text, "b.nv") && strings.HasPrefix(text, "b.al") {
    87  		return true
    88  	}
    89  	// GNU objdump recognizes invalid binaries as following instructions
    90  	if hasPrefix(dec.text, "hint", "mrs", "msr", "bfc", "orr", "mov") {
    91  		return true
    92  	}
    93  	if strings.HasPrefix(text, "hint") {
    94  		return true
    95  	}
    96  	// GNU objdump recognizes reserved valuse as valid ones
    97  	if strings.Contains(text, "unknown instruction") && hasPrefix(dec.text, "fmla", "fmul", "fmulx", "fcvtzs", "fcvtzu", "fmls", "fmov", "scvtf", "ucvtf") {
    98  		return true
    99  	}
   100  	// Some old objdump recognizes ldur*/stur*/prfum as ldr*/str*/prfm
   101  	for k, v := range oldObjdumpMismatch {
   102  		if strings.HasPrefix(dec.text, k) && strings.Replace(dec.text, k, v, 1) == text {
   103  			return true
   104  		}
   105  	}
   106  	// New objdump supports some newer mnemonics than this package. This
   107  	// package should be updated to support the new mnemonics and the sense
   108  	// of this reversed to continue passing with older objdumps but that
   109  	// requires internal ARM tooling.
   110  	if newForm, ok := newMnemonics[text]; ok && newForm == dec.text {
   111  		return true
   112  	}
   113  	// GNU objdump misses spaces between operands for some instructions (e.g., "ld1 {v10.2s, v11.2s}, [x23],#16")
   114  	if strings.Replace(text, " ", "", -1) == strings.Replace(dec.text, " ", "", -1) {
   115  		return true
   116  	}
   117  	return false
   118  }
   119  
   120  // TODO: system instruction.
   121  var todo = strings.Fields(`
   122  	sys
   123  	at
   124  	ic
   125  	hvc
   126  	smc
   127  `)
   128  
   129  // Following instructions can't be covered because they are just aliases to another instructions which are always preferred
   130  var Ncover = strings.Fields(`
   131  	sbfm
   132  	asrv
   133  	bfm
   134  	ubfm
   135  	lslv
   136  	lsrv
   137  	rorv
   138  	ins
   139  	dup
   140  `)
   141  
   142  // Some old objdump wrongly decodes following instructions and allow their mismatches to avoid false alarm
   143  var oldObjdumpMismatch = map[string]string{
   144  	//oldObjValue	correctValue
   145  	"ldr":   "ldur",
   146  	"ldrb":  "ldurb",
   147  	"ldrh":  "ldurh",
   148  	"ldrsb": "ldursb",
   149  	"ldrsh": "ldursh",
   150  	"ldrsw": "ldursw",
   151  	"str":   "stur",
   152  	"strb":  "sturb",
   153  	"strh":  "sturh",
   154  	"prfm":  "prfum",
   155  }
   156  
   157  var newMnemonics = map[string]string{
   158  	"dsb #0x00": "ssbb",
   159  	"dsb #0x04": "pssbb",
   160  }
   161  

View as plain text