golang.org/x/arch@v0.17.0/arm/armasm/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 armasm 6 7 import ( 8 "encoding/binary" 9 "strings" 10 "testing" 11 ) 12 13 func TestObjdumpARMTestdata(t *testing.T) { testObjdumpARM(t, testdataCases(t)) } 14 func TestObjdumpARMManual(t *testing.T) { testObjdumpARM(t, hexCases(t, objdumpManualTests)) } 15 func TestObjdumpARMCond(t *testing.T) { testObjdumpARM(t, condCases(t)) } 16 func TestObjdumpARMUncond(t *testing.T) { testObjdumpARM(t, uncondCases(t)) } 17 func TestObjdumpARMVFP(t *testing.T) { testObjdumpARM(t, vfpCases(t)) } 18 19 // objdumpManualTests holds test cases that will be run by TestObjdumpARMManual. 20 // If you are debugging a few cases that turned up in a longer run, it can be useful 21 // to list them here and then use -run=Manual, particularly with tracing enabled. 22 // Note that these are byte sequences, so they must be reversed from the usual 23 // word presentation. 24 var objdumpManualTests = ` 25 002a9b1d 26 001b9bed 27 020b8ded 28 003a9b1d 29 060b8ded 30 fcde1100 31 b4de1100 32 bc480000 33 0b008de7 34 0b00ade7 35 fdbcfaf7 36 ` 37 38 // allowedMismatchObjdump reports whether the mismatch between text and dec 39 // should be allowed by the test. 40 func allowedMismatchObjdump(text string, size int, inst *Inst, dec ExtInst) bool { 41 if hasPrefix(text, "error:") { 42 if hasPrefix(dec.text, unsupported...) || strings.Contains(dec.text, "invalid:") || strings.HasSuffix(dec.text, "^") || strings.Contains(dec.text, "f16.f64") || strings.Contains(dec.text, "f64.f16") { 43 return true 44 } 45 // word 4320F02C: libopcodes says 'nopmi {44}'. 46 if hasPrefix(dec.text, "nop") && strings.Contains(dec.text, "{") { 47 return true 48 } 49 } 50 51 if hasPrefix(dec.text, "error:") && text == "undef" && inst.Enc == 0xf7fabcfd { 52 return true 53 } 54 55 // word 00f02053: libopcodes says 'noppl {0}'. 56 if hasPrefix(dec.text, "nop") && hasPrefix(text, "nop") && dec.text == text+" {0}" { 57 return true 58 } 59 60 // word F57FF04F. we say 'dsb #15', libopcodes says 'dsb sy'. 61 if hasPrefix(text, "dsb") && hasPrefix(dec.text, "dsb") { 62 return true 63 } 64 // word F57FF06F. we say 'isb #15', libopcodes says 'isb sy'. 65 if hasPrefix(text, "isb") && hasPrefix(dec.text, "isb") { 66 return true 67 } 68 // word F57FF053. we say 'dmb #3', libopcodes says 'dmb osh'. 69 if hasPrefix(text, "dmb") && hasPrefix(dec.text, "dmb") { 70 return true 71 } 72 73 // word 992D0000. push/stmdb with no registers (undefined). 74 // we say 'stmdbls sp!, {}', libopcodes says 'pushls {}'. 75 if hasPrefix(text, "stmdb") && hasPrefix(dec.text, "push") && strings.Contains(text, "{}") && strings.Contains(dec.text, "{}") { 76 return true 77 } 78 79 // word 28BD0000. pop/ldm with no registers (undefined). 80 // we say 'ldmcs sp!, {}', libopcodes says 'popcs {}'. 81 if hasPrefix(text, "ldm") && hasPrefix(dec.text, "pop") && strings.Contains(text, "{}") && strings.Contains(dec.text, "{}") { 82 return true 83 } 84 85 // word 014640F0. 86 // libopcodes emits #-0 for negative zero; we don't. 87 if strings.Replace(dec.text, "#-0", "#0", -1) == text || strings.Replace(dec.text, ", #-0", "", -1) == text { 88 return true 89 } 90 91 // word 91EF90F0. we say 'strdls r9, [pc, #0]!' but libopcodes says 'strdls r9, [pc]'. 92 // word D16F60F0. we say 'strdle r6, [pc, #0]!' but libopcodes says 'strdle r6, [pc, #-0]'. 93 if strings.Replace(text, ", #0]!", "]", -1) == strings.Replace(dec.text, ", #-0]", "]", -1) { 94 return true 95 } 96 97 // word 510F4000. we say apsr, libopcodes says CPSR. 98 if strings.Replace(dec.text, "CPSR", "apsr", -1) == text { 99 return true 100 } 101 102 // word 06A4B059. 103 // for ssat and usat, libopcodes decodes asr #0 as asr #0 but the manual seems to say it should be asr #32. 104 // There is never an asr #0. 105 if strings.Replace(dec.text, ", asr #0", ", asr #32", -1) == text { 106 return true 107 } 108 109 if len(dec.enc) >= 4 { 110 raw := binary.LittleEndian.Uint32(dec.enc[:4]) 111 112 // word 21FFF0B5. 113 // the manual is clear that this is pre-indexed mode (with !) but libopcodes generates post-index (without !). 114 if raw&0x01200000 == 0x01200000 && strings.Replace(text, "!", "", -1) == dec.text { 115 return true 116 } 117 118 // word C100543E: libopcodes says tst, but no evidence for that. 119 if strings.HasPrefix(dec.text, "tst") && raw&0x0ff00000 != 0x03100000 && raw&0x0ff00000 != 0x01100000 { 120 return true 121 } 122 123 // word C3203CE8: libopcodes says teq, but no evidence for that. 124 if strings.HasPrefix(dec.text, "teq") && raw&0x0ff00000 != 0x03300000 && raw&0x0ff00000 != 0x01300000 { 125 return true 126 } 127 128 // word D14C552E: libopcodes says cmp but no evidence for that. 129 if strings.HasPrefix(dec.text, "cmp") && raw&0x0ff00000 != 0x03500000 && raw&0x0ff00000 != 0x01500000 { 130 return true 131 } 132 133 // word 2166AA4A: libopcodes says cmn but no evidence for that. 134 if strings.HasPrefix(dec.text, "cmn") && raw&0x0ff00000 != 0x03700000 && raw&0x0ff00000 != 0x01700000 { 135 return true 136 } 137 138 // word E70AEEEF: libopcodes says str but no evidence for that. 139 if strings.HasPrefix(dec.text, "str") && len(dec.text) >= 5 && (dec.text[3] == ' ' || dec.text[5] == ' ') && raw&0x0e500018 != 0x06000000 && raw&0x0e500000 != 0x0400000 { 140 return true 141 } 142 143 // word B0AF48F4: libopcodes says strd but P=0,W=1 which is unpredictable. 144 if hasPrefix(dec.text, "ldr", "str") && raw&0x01200000 == 0x00200000 { 145 return true 146 } 147 148 // word B6CC1C76: libopcodes inexplicably says 'uxtab16lt r1, ip, r6, ROR #24' instead of 'uxtab16lt r1, ip, r6, ror #24' 149 if strings.ToLower(dec.text) == text { 150 return true 151 } 152 153 // word F410FDA1: libopcodes says PLDW but the manual is clear that PLDW is F5/F7, not F4. 154 // word F7D0FB17: libopcodes says PLDW but the manual is clear that PLDW has 0x10 clear 155 if hasPrefix(dec.text, "pld") && raw&0xfd000010 != 0xf5000000 { 156 return true 157 } 158 159 // word F650FE14: libopcodes says PLI but the manual is clear that PLI has 0x10 clear 160 if hasPrefix(dec.text, "pli") && raw&0xff000010 != 0xf6000000 { 161 return true 162 } 163 } 164 165 return false 166 } 167 168 // Instructions known to libopcodes (or xed) but not to us. 169 // Most of these are floating point coprocessor instructions. 170 var unsupported = strings.Fields(` 171 abs 172 acs 173 adf 174 aes 175 asn 176 atn 177 cdp 178 cf 179 cmf 180 cnf 181 cos 182 cps 183 crc32 184 dvf 185 eret 186 exp 187 fadd 188 fcmp 189 fcpy 190 fcvt 191 fdiv 192 fdv 193 fix 194 fld 195 flt 196 fmac 197 fmd 198 fml 199 fmr 200 fms 201 fmul 202 fmx 203 fneg 204 fnm 205 frd 206 fsit 207 fsq 208 fst 209 fsu 210 fto 211 fui 212 hlt 213 hvc 214 lda 215 ldc 216 ldf 217 lfm 218 lgn 219 log 220 mar 221 mcr 222 mcrr 223 mia 224 mnf 225 mra 226 mrc 227 mrrc 228 mrs 229 msr 230 msr 231 muf 232 mvf 233 nrm 234 pol 235 pow 236 rdf 237 rfc 238 rfe 239 rfs 240 rmf 241 rnd 242 rpw 243 rsf 244 sdiv 245 sev 246 sfm 247 sha1 248 sha256 249 sin 250 smc 251 sqt 252 srs 253 stc 254 stf 255 stl 256 suf 257 tan 258 udf 259 udiv 260 urd 261 vfma 262 vfms 263 vfnma 264 vfnms 265 vrint 266 wfc 267 wfs 268 `)