1 2 // line 1 "SyntheticAccessorFSM.rl" 3 /* 4 * Copyright 2012, Google Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following disclaimer 15 * in the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Google Inc. nor the names of its 18 * contributors may be used to endorse or promote products derived from 19 * this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 package org.jf.dexlib2.util; 35 36 import org.jf.dexlib2.Opcodes; 37 import org.jf.dexlib2.iface.instruction.Instruction; 38 import org.jf.dexlib2.iface.instruction.OneRegisterInstruction; 39 import org.jf.dexlib2.iface.instruction.WideLiteralInstruction; 40 41 import javax.annotation.Nonnull; 42 import java.util.List; 43 44 public class SyntheticAccessorFSM { 45 46 // line 43 "SyntheticAccessorFSM.rl" 47 48 // line 48 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" 49 private static byte[] init__SyntheticAccessorFSM_actions_0() 50 { 51 return new byte [] { 52 0, 1, 0, 1, 1, 1, 2, 1, 13, 1, 14, 1, 53 15, 1, 16, 1, 17, 1, 18, 1, 19, 1, 20, 1, 54 21, 1, 25, 2, 3, 7, 2, 4, 7, 2, 5, 7, 55 2, 6, 7, 2, 8, 12, 2, 9, 12, 2, 10, 12, 56 2, 11, 12, 2, 22, 23, 2, 22, 24, 2, 22, 25, 57 2, 22, 26, 2, 22, 27, 2, 22, 28 58 }; 59 } 60 61 private static final byte _SyntheticAccessorFSM_actions[] = init__SyntheticAccessorFSM_actions_0(); 62 63 64 private static short[] init__SyntheticAccessorFSM_key_offsets_0() 65 { 66 return new short [] { 67 0, 0, 12, 82, 98, 102, 104, 166, 172, 174, 180, 184, 68 190, 192, 196, 198, 201, 203 69 }; 70 } 71 72 private static final short _SyntheticAccessorFSM_key_offsets[] = init__SyntheticAccessorFSM_key_offsets_0(); 73 74 75 private static short[] init__SyntheticAccessorFSM_trans_keys_0() 76 { 77 return new short [] { 78 82, 88, 89, 95, 96, 102, 103, 109, 110, 114, 116, 120, 79 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 80 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 81 169, 170, 171, 172, 173, 174, 175, 177, 179, 180, 181, 182, 82 183, 184, 185, 186, 187, 188, 190, 191, 192, 193, 194, 195, 83 196, 197, 198, 199, 201, 202, 203, 204, 206, 207, 208, 216, 84 15, 17, 18, 25, 129, 143, 144, 176, 178, 205, 144, 145, 85 155, 156, 166, 167, 171, 172, 176, 177, 187, 188, 198, 199, 86 203, 204, 89, 95, 103, 109, 15, 17, 145, 146, 147, 148, 87 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 88 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 89 173, 174, 175, 177, 179, 180, 181, 182, 183, 184, 185, 186, 90 187, 188, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 91 201, 202, 203, 204, 206, 207, 144, 176, 178, 205, 89, 95, 92 103, 109, 129, 143, 15, 17, 89, 95, 103, 109, 129, 143, 93 89, 95, 103, 109, 89, 95, 103, 109, 129, 143, 15, 17, 94 89, 95, 103, 109, 15, 17, 14, 10, 12, 15, 17, 0 95 }; 96 } 97 98 private static final short _SyntheticAccessorFSM_trans_keys[] = init__SyntheticAccessorFSM_trans_keys_0(); 99 100 101 private static byte[] init__SyntheticAccessorFSM_single_lengths_0() 102 { 103 return new byte [] { 104 0, 0, 60, 16, 0, 0, 58, 0, 0, 0, 0, 0, 105 0, 0, 0, 1, 0, 0 106 }; 107 } 108 109 private static final byte _SyntheticAccessorFSM_single_lengths[] = init__SyntheticAccessorFSM_single_lengths_0(); 110 111 112 private static byte[] init__SyntheticAccessorFSM_range_lengths_0() 113 { 114 return new byte [] { 115 0, 6, 5, 0, 2, 1, 2, 3, 1, 3, 2, 3, 116 1, 2, 1, 1, 1, 0 117 }; 118 } 119 120 private static final byte _SyntheticAccessorFSM_range_lengths[] = init__SyntheticAccessorFSM_range_lengths_0(); 121 122 123 private static short[] init__SyntheticAccessorFSM_index_offsets_0() 124 { 125 return new short [] { 126 0, 0, 7, 73, 90, 93, 95, 156, 160, 162, 166, 169, 127 173, 175, 178, 180, 183, 185 128 }; 129 } 130 131 private static final short _SyntheticAccessorFSM_index_offsets[] = init__SyntheticAccessorFSM_index_offsets_0(); 132 133 134 private static byte[] init__SyntheticAccessorFSM_indicies_0() 135 { 136 return new byte [] { 137 0, 2, 0, 2, 3, 3, 1, 8, 9, 10, 11, 12, 138 13, 14, 15, 16, 17, 18, 19, 9, 10, 11, 12, 13, 139 14, 15, 16, 17, 20, 21, 9, 10, 11, 22, 23, 9, 140 10, 11, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 141 19, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 10, 142 11, 22, 23, 10, 11, 24, 24, 4, 5, 6, 7, 9, 143 1, 25, 26, 27, 28, 29, 30, 31, 32, 25, 26, 27, 144 28, 29, 30, 31, 32, 1, 33, 33, 1, 34, 1, 8, 145 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 9, 146 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 9, 10, 147 11, 22, 23, 9, 10, 11, 8, 10, 11, 12, 13, 14, 148 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 15, 16, 149 17, 20, 21, 10, 11, 22, 23, 10, 11, 7, 9, 1, 150 35, 35, 36, 1, 37, 1, 35, 35, 38, 1, 35, 35, 151 1, 39, 39, 40, 1, 41, 1, 39, 39, 1, 42, 1, 152 44, 43, 1, 45, 1, 1, 0 153 }; 154 } 155 156 private static final byte _SyntheticAccessorFSM_indicies[] = init__SyntheticAccessorFSM_indicies_0(); 157 158 159 private static byte[] init__SyntheticAccessorFSM_trans_targs_0() 160 { 161 return new byte [] { 162 2, 0, 14, 15, 17, 3, 6, 7, 7, 7, 7, 7, 163 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 164 11, 4, 4, 4, 4, 4, 4, 4, 4, 5, 17, 8, 165 9, 17, 10, 12, 13, 17, 17, 16, 17, 17 166 }; 167 } 168 169 private static final byte _SyntheticAccessorFSM_trans_targs[] = init__SyntheticAccessorFSM_trans_targs_0(); 170 171 172 private static byte[] init__SyntheticAccessorFSM_trans_actions_0() 173 { 174 return new byte [] { 175 0, 0, 1, 0, 51, 3, 0, 27, 39, 7, 9, 11, 176 13, 15, 17, 19, 21, 23, 30, 42, 33, 45, 36, 48, 177 5, 27, 39, 30, 42, 33, 45, 36, 48, 1, 63, 1, 178 0, 66, 0, 1, 0, 60, 54, 0, 25, 57 179 }; 180 } 181 182 private static final byte _SyntheticAccessorFSM_trans_actions[] = init__SyntheticAccessorFSM_trans_actions_0(); 183 184 185 static final int SyntheticAccessorFSM_start = 1; 186 static final int SyntheticAccessorFSM_first_final = 17; 187 static final int SyntheticAccessorFSM_error = 0; 188 189 static final int SyntheticAccessorFSM_en_main = 1; 190 191 192 // line 44 "SyntheticAccessorFSM.rl" 193 194 // math type constants 195 public static final int ADD = SyntheticAccessorResolver.ADD_ASSIGNMENT; 196 public static final int SUB = SyntheticAccessorResolver.SUB_ASSIGNMENT; 197 public static final int MUL = SyntheticAccessorResolver.MUL_ASSIGNMENT; 198 public static final int DIV = SyntheticAccessorResolver.DIV_ASSIGNMENT; 199 public static final int REM = SyntheticAccessorResolver.REM_ASSIGNMENT; 200 public static final int AND = SyntheticAccessorResolver.AND_ASSIGNMENT; 201 public static final int OR = SyntheticAccessorResolver.OR_ASSIGNMENT; 202 public static final int XOR = SyntheticAccessorResolver.XOR_ASSIGNMENT; 203 public static final int SHL = SyntheticAccessorResolver.SHL_ASSIGNMENT; 204 public static final int SHR = SyntheticAccessorResolver.SHR_ASSIGNMENT; 205 public static final int USHR = SyntheticAccessorResolver.USHR_ASSIGNMENT; 206 207 public static final int INT = 0; 208 public static final int LONG = 1; 209 public static final int FLOAT = 2; 210 public static final int DOUBLE = 3; 211 212 public static final int POSITIVE_ONE = 1; 213 public static final int NEGATIVE_ONE = -1; 214 public static final int OTHER = 0; 215 216 @Nonnull private final Opcodes opcodes; 217 218 public SyntheticAccessorFSM(@Nonnull Opcodes opcodes) { 219 this.opcodes = opcodes; 220 } 221 222 public int test(List<? extends Instruction> instructions) { 223 int accessorType = -1; 224 int cs, p = 0; 225 int pe = instructions.size(); 226 227 // one of the math type constants representing the type of math operation being performed 228 int mathOp = -1; 229 230 // for increments an decrements, the type of value the math operation is on 231 int mathType = -1; 232 233 // for increments and decrements, the value of the constant that is used 234 long constantValue = 0; 235 236 // The source register for the put instruction 237 int putRegister = -1; 238 // The return register; 239 int returnRegister = -1; 240 241 242 // line 242 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" 243 { 244 cs = SyntheticAccessorFSM_start; 245 } 246 247 // line 247 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" 248 { 249 int _klen; 250 int _trans = 0; 251 int _acts; 252 int _nacts; 253 int _keys; 254 int _goto_targ = 0; 255 256 _goto: while (true) { 257 switch ( _goto_targ ) { 258 case 0: 259 if ( p == pe ) { 260 _goto_targ = 4; 261 continue _goto; 262 } 263 if ( cs == 0 ) { 264 _goto_targ = 5; 265 continue _goto; 266 } 267 case 1: 268 _match: do { 269 _keys = _SyntheticAccessorFSM_key_offsets[cs]; 270 _trans = _SyntheticAccessorFSM_index_offsets[cs]; 271 _klen = _SyntheticAccessorFSM_single_lengths[cs]; 272 if ( _klen > 0 ) { 273 int _lower = _keys; 274 int _mid; 275 int _upper = _keys + _klen - 1; 276 while (true) { 277 if ( _upper < _lower ) 278 break; 279 280 _mid = _lower + ((_upper-_lower) >> 1); 281 if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) < _SyntheticAccessorFSM_trans_keys[_mid] ) 282 _upper = _mid - 1; 283 else if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) > _SyntheticAccessorFSM_trans_keys[_mid] ) 284 _lower = _mid + 1; 285 else { 286 _trans += (_mid - _keys); 287 break _match; 288 } 289 } 290 _keys += _klen; 291 _trans += _klen; 292 } 293 294 _klen = _SyntheticAccessorFSM_range_lengths[cs]; 295 if ( _klen > 0 ) { 296 int _lower = _keys; 297 int _mid; 298 int _upper = _keys + (_klen<<1) - 2; 299 while (true) { 300 if ( _upper < _lower ) 301 break; 302 303 _mid = _lower + (((_upper-_lower) >> 1) & ~1); 304 if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) < _SyntheticAccessorFSM_trans_keys[_mid] ) 305 _upper = _mid - 2; 306 else if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) > _SyntheticAccessorFSM_trans_keys[_mid+1] ) 307 _lower = _mid + 2; 308 else { 309 _trans += ((_mid - _keys)>>1); 310 break _match; 311 } 312 } 313 _trans += _klen; 314 } 315 } while (false); 316 317 _trans = _SyntheticAccessorFSM_indicies[_trans]; 318 cs = _SyntheticAccessorFSM_trans_targs[_trans]; 319 320 if ( _SyntheticAccessorFSM_trans_actions[_trans] != 0 ) { 321 _acts = _SyntheticAccessorFSM_trans_actions[_trans]; 322 _nacts = (int) _SyntheticAccessorFSM_actions[_acts++]; 323 while ( _nacts-- > 0 ) 324 { 325 switch ( _SyntheticAccessorFSM_actions[_acts++] ) 326 { 327 case 0: 328 // line 100 "SyntheticAccessorFSM.rl" 329 { 330 putRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA(); 331 } 332 break; 333 case 1: 334 // line 107 "SyntheticAccessorFSM.rl" 335 { 336 constantValue = ((WideLiteralInstruction)instructions.get(p)).getWideLiteral(); 337 } 338 break; 339 case 2: 340 // line 111 "SyntheticAccessorFSM.rl" 341 { 342 mathType = INT; 343 mathOp = ADD; 344 constantValue = ((WideLiteralInstruction)instructions.get(p)).getWideLiteral(); 345 } 346 break; 347 case 3: 348 // line 117 "SyntheticAccessorFSM.rl" 349 { mathType = INT; } 350 break; 351 case 4: 352 // line 118 "SyntheticAccessorFSM.rl" 353 { mathType = LONG; } 354 break; 355 case 5: 356 // line 119 "SyntheticAccessorFSM.rl" 357 { mathType = FLOAT; } 358 break; 359 case 6: 360 // line 120 "SyntheticAccessorFSM.rl" 361 {mathType = DOUBLE; } 362 break; 363 case 7: 364 // line 120 "SyntheticAccessorFSM.rl" 365 { 366 mathOp = ADD; 367 } 368 break; 369 case 8: 370 // line 123 "SyntheticAccessorFSM.rl" 371 { mathType = INT; } 372 break; 373 case 9: 374 // line 124 "SyntheticAccessorFSM.rl" 375 { mathType = LONG; } 376 break; 377 case 10: 378 // line 125 "SyntheticAccessorFSM.rl" 379 { mathType = FLOAT; } 380 break; 381 case 11: 382 // line 126 "SyntheticAccessorFSM.rl" 383 {mathType = DOUBLE; } 384 break; 385 case 12: 386 // line 126 "SyntheticAccessorFSM.rl" 387 { 388 mathOp = SUB; 389 } 390 break; 391 case 13: 392 // line 130 "SyntheticAccessorFSM.rl" 393 { 394 mathOp = MUL; 395 } 396 break; 397 case 14: 398 // line 134 "SyntheticAccessorFSM.rl" 399 { 400 mathOp = DIV; 401 } 402 break; 403 case 15: 404 // line 138 "SyntheticAccessorFSM.rl" 405 { 406 mathOp = REM; 407 } 408 break; 409 case 16: 410 // line 141 "SyntheticAccessorFSM.rl" 411 { 412 mathOp = AND; 413 } 414 break; 415 case 17: 416 // line 144 "SyntheticAccessorFSM.rl" 417 { 418 mathOp = OR; 419 } 420 break; 421 case 18: 422 // line 147 "SyntheticAccessorFSM.rl" 423 { 424 mathOp = XOR; 425 } 426 break; 427 case 19: 428 // line 150 "SyntheticAccessorFSM.rl" 429 { 430 mathOp = SHL; 431 } 432 break; 433 case 20: 434 // line 153 "SyntheticAccessorFSM.rl" 435 { 436 mathOp = SHR; 437 } 438 break; 439 case 21: 440 // line 156 "SyntheticAccessorFSM.rl" 441 { 442 mathOp = USHR; 443 } 444 break; 445 case 22: 446 // line 162 "SyntheticAccessorFSM.rl" 447 { 448 returnRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA(); 449 } 450 break; 451 case 23: 452 // line 168 "SyntheticAccessorFSM.rl" 453 { 454 accessorType = SyntheticAccessorResolver.GETTER; { p += 1; _goto_targ = 5; if (true) continue _goto;} 455 } 456 break; 457 case 24: 458 // line 172 "SyntheticAccessorFSM.rl" 459 { 460 accessorType = SyntheticAccessorResolver.SETTER; { p += 1; _goto_targ = 5; if (true) continue _goto;} 461 } 462 break; 463 case 25: 464 // line 176 "SyntheticAccessorFSM.rl" 465 { 466 accessorType = SyntheticAccessorResolver.METHOD; { p += 1; _goto_targ = 5; if (true) continue _goto;} 467 } 468 break; 469 case 26: 470 // line 180 "SyntheticAccessorFSM.rl" 471 { 472 accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister); 473 } 474 break; 475 case 27: 476 // line 184 "SyntheticAccessorFSM.rl" 477 { 478 accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister); 479 } 480 break; 481 case 28: 482 // line 192 "SyntheticAccessorFSM.rl" 483 { 484 accessorType = mathOp; { p += 1; _goto_targ = 5; if (true) continue _goto;} 485 } 486 break; 487 // line 487 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" 488 } 489 } 490 } 491 492 case 2: 493 if ( cs == 0 ) { 494 _goto_targ = 5; 495 continue _goto; 496 } 497 if ( ++p != pe ) { 498 _goto_targ = 1; 499 continue _goto; 500 } 501 case 4: 502 case 5: 503 } 504 break; } 505 } 506 507 // line 205 "SyntheticAccessorFSM.rl" 508 509 510 return accessorType; 511 } 512 513 private static int getIncrementType(int mathOp, int mathType, long constantValue, int putRegister, 514 int returnRegister) { 515 boolean isPrefix = putRegister == returnRegister; 516 517 boolean negativeConstant = false; 518 519 switch (mathType) { 520 case INT: 521 case LONG: { 522 if (constantValue == 1) { 523 negativeConstant = false; 524 } else if (constantValue == -1) { 525 negativeConstant = true; 526 } else { 527 return -1; 528 } 529 break; 530 } 531 case FLOAT: { 532 float val = Float.intBitsToFloat((int)constantValue); 533 if (val == 1) { 534 negativeConstant = false; 535 } else if (val == -1) { 536 negativeConstant = true; 537 } else { 538 return -1; 539 } 540 break; 541 } 542 case DOUBLE: { 543 double val = Double.longBitsToDouble(constantValue); 544 if (val == 1) { 545 negativeConstant = false; 546 } else if (val == -1) { 547 negativeConstant = true; 548 } else { 549 return -1; 550 } 551 break; 552 } 553 } 554 555 boolean isAdd = ((mathOp == ADD) && !negativeConstant) || 556 ((mathOp == SUB) && negativeConstant); 557 558 if (isPrefix) { 559 if (isAdd) { 560 return SyntheticAccessorResolver.PREFIX_INCREMENT; 561 } else { 562 return SyntheticAccessorResolver.PREFIX_DECREMENT; 563 } 564 } else { 565 if (isAdd) { 566 return SyntheticAccessorResolver.POSTFIX_INCREMENT; 567 } else { 568 return SyntheticAccessorResolver.POSTFIX_DECREMENT; 569 } 570 } 571 } 572 }