■ ■ ■ ■ ■ ■
jadx-gui/src/main/java/jadx/gui/device/debugger/smali/Smali.java
| skipped 12 lines |
13 | 13 | | |
14 | 14 | | import org.jetbrains.annotations.NotNull; |
15 | 15 | | import org.jetbrains.annotations.Nullable; |
| 16 | + | import org.slf4j.Logger; |
| 17 | + | import org.slf4j.LoggerFactory; |
16 | 18 | | |
17 | 19 | | import jadx.api.ICodeInfo; |
18 | 20 | | import jadx.api.plugins.input.data.AccessFlags; |
| skipped 27 lines |
46 | 48 | | import jadx.core.dex.nodes.ClassNode; |
47 | 49 | | import jadx.core.dex.nodes.InsnNode; |
48 | 50 | | import jadx.core.dex.nodes.MethodNode; |
| 51 | + | import jadx.core.utils.Utils; |
49 | 52 | | import jadx.core.utils.exceptions.JadxRuntimeException; |
50 | 53 | | |
51 | 54 | | import static jadx.api.plugins.input.data.AccessFlagsScope.FIELD; |
| skipped 15 lines |
67 | 70 | | import static jadx.api.plugins.input.insns.Opcode.SPARSE_SWITCH_PAYLOAD; |
68 | 71 | | |
69 | 72 | | public class Smali { |
| 73 | + | private static final Logger LOG = LoggerFactory.getLogger(Smali.class); |
70 | 74 | | |
71 | 75 | | private static SmaliInsnDecoder insnDecoder = null; |
72 | 76 | | |
| skipped 146 lines |
219 | 223 | | writeFields(smali, clsData, fields, colWidths); |
220 | 224 | | fields.clear(); |
221 | 225 | | } |
222 | | - | writeMethod(smali, cls.getMethods().get(mthIndex[0]++), m, line); |
| 226 | + | try { |
| 227 | + | writeMethod(smali, cls.getMethods().get(mthIndex[0]++), m, line); |
| 228 | + | } catch (Throwable e) { |
| 229 | + | IMethodRef methodRef = m.getMethodRef(); |
| 230 | + | String mthFullName = methodRef.getParentClassType() + "->" + methodRef.getName(); |
| 231 | + | smali.setIndent(0); |
| 232 | + | smali.startLine("Failed to write method: " + mthFullName + "\n" + Utils.getStackTrace(e)); |
| 233 | + | LOG.error("Failed to write smali code for method: {}", mthFullName, e); |
| 234 | + | } |
223 | 235 | | line.reset(); |
224 | 236 | | }); |
225 | 237 | | |
| skipped 225 lines |
451 | 463 | | if (types.isEmpty()) { |
452 | 464 | | return false; |
453 | 465 | | } |
454 | | - | int paramCount = 0; |
| 466 | + | ILocalVar[] params = new ILocalVar[codeReader.getRegistersCount()]; |
| 467 | + | IDebugInfo dbgInfo = codeReader.getDebugInfo(); |
| 468 | + | if (dbgInfo != null) { |
| 469 | + | for (ILocalVar var : dbgInfo.getLocalVars()) { |
| 470 | + | // collect only method parameters |
| 471 | + | if (var.getStartOffset() <= 0) { |
| 472 | + | params[var.getRegNum()] = var; |
| 473 | + | } |
| 474 | + | } |
| 475 | + | } |
455 | 476 | | int paramStart = 0; |
456 | 477 | | int regNum = line.smaliMthNode.getParamRegStart(); |
457 | 478 | | if (!hasStaticFlag(mth.getAccessFlags())) { |
| 479 | + | // add 'this' register |
458 | 480 | | line.addRegName(regNum, "p0"); |
459 | 481 | | line.smaliMthNode.setParamReg(regNum, "p0"); |
460 | | - | regNum += 1; |
461 | | - | paramStart = 1; |
| 482 | + | regNum++; |
| 483 | + | paramStart++; |
462 | 484 | | } |
463 | | - | IDebugInfo dbgInfo = codeReader.getDebugInfo(); |
464 | | - | if (dbgInfo != null) { |
465 | | - | for (ILocalVar var : dbgInfo.getLocalVars()) { |
466 | | - | if (var.getRegNum() == regNum) { |
467 | | - | int i = writeParamInfo(smali, line, regNum, paramStart, var.getName(), var.getType()); |
468 | | - | regNum += i; |
469 | | - | paramStart += i; |
470 | | - | paramCount++; |
471 | | - | } |
| 485 | + | for (String paramType : types) { |
| 486 | + | String name; |
| 487 | + | String type; |
| 488 | + | ILocalVar param = params[regNum]; |
| 489 | + | if (param != null) { |
| 490 | + | name = Utils.getOrElse(param.getName(), ""); |
| 491 | + | type = Utils.getOrElse(param.getSignature(), paramType); |
| 492 | + | } else { |
| 493 | + | name = ""; |
| 494 | + | type = paramType; |
472 | 495 | | } |
473 | | - | } |
474 | | - | for (; paramCount < types.size(); paramCount++) { |
475 | | - | int i = writeParamInfo(smali, line, regNum, paramStart, "", types.get(paramCount)); |
476 | | - | regNum += i; |
477 | | - | paramStart += i; |
| 496 | + | String varName = "p" + paramStart; |
| 497 | + | smali.startLine(String.format(".param %s, \"%s\" # %s", varName, name, type)); |
| 498 | + | line.addRegName(regNum, varName); |
| 499 | + | line.smaliMthNode.setParamReg(regNum, varName); |
| 500 | + | int regSize = isWideType(paramType) ? 2 : 1; |
| 501 | + | regNum += regSize; |
| 502 | + | paramStart += regSize; |
478 | 503 | | } |
479 | 504 | | return true; |
480 | | - | } |
481 | | - | |
482 | | - | private static int writeParamInfo(SmaliWriter smali, LineInfo line, |
483 | | - | int regNum, int paramNum, String dbgInfoName, String type) { |
484 | | - | smali.startLine(String.format(".param p%d, \"%s\":%s", paramNum, dbgInfoName, type)); |
485 | | - | String pName = "p" + paramNum; |
486 | | - | line.addRegName(regNum, pName); |
487 | | - | line.smaliMthNode.setParamReg(regNum, pName); |
488 | | - | if (isWideType(type)) { |
489 | | - | regNum++; |
490 | | - | dbgInfoName = "p" + (paramNum + 1); |
491 | | - | line.addRegName(regNum, dbgInfoName); |
492 | | - | line.smaliMthNode.setParamReg(regNum, dbgInfoName); |
493 | | - | return 2; |
494 | | - | } |
495 | | - | return 1; |
496 | 505 | | } |
497 | 506 | | |
498 | 507 | | private static int getParamStartRegNum(IMethodData mth) { |
| skipped 565 lines |