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