golang.org/x/arch@v0.17.0/arm64/arm64asm/objdump_test.go (about) 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 }