Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2301_76393173
jadx
提交
a71b3a71
J
jadx
项目概览
2301_76393173
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
a71b3a71
编写于
4月 26, 2022
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: better code styling for `if-else` blocks (#1455)
上级
3366bf3d
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
753 addition
and
115 deletion
+753
-115
jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java
jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java
+1
-0
jadx-core/src/main/java/jadx/core/dex/regions/conditions/IfCondition.java
...in/java/jadx/core/dex/regions/conditions/IfCondition.java
+10
-0
jadx-core/src/main/java/jadx/core/dex/visitors/debuginfo/DebugInfoAttachVisitor.java
...x/core/dex/visitors/debuginfo/DebugInfoAttachVisitor.java
+18
-1
jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfRegionVisitor.java
.../java/jadx/core/dex/visitors/regions/IfRegionVisitor.java
+71
-51
jadx-core/src/main/java/jadx/core/dex/visitors/regions/TernaryMod.java
.../main/java/jadx/core/dex/visitors/regions/TernaryMod.java
+4
-1
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
+24
-3
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
+79
-11
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
+3
-3
jadx-core/src/test/java/jadx/tests/integration/conditions/TestBitwiseAnd.java
...ava/jadx/tests/integration/conditions/TestBitwiseAnd.java
+1
-0
jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions14.java
...a/jadx/tests/integration/conditions/TestConditions14.java
+1
-0
jadx-core/src/test/java/jadx/tests/integration/conditions/TestIfCodeStyle.java
...va/jadx/tests/integration/conditions/TestIfCodeStyle.java
+160
-0
jadx-core/src/test/java/jadx/tests/integration/debuginfo/TestLineNumbers2.java
...va/jadx/tests/integration/debuginfo/TestLineNumbers2.java
+5
-6
jadx-core/src/test/java/jadx/tests/integration/loops/TestSequentialLoops.java
...ava/jadx/tests/integration/loops/TestSequentialLoops.java
+6
-14
jadx-core/src/test/java/jadx/tests/integration/trycatch/TestLoopInTryCatch.java
...a/jadx/tests/integration/trycatch/TestLoopInTryCatch.java
+4
-2
jadx-core/src/test/smali/conditions/TestIfCodeStyle.smali
jadx-core/src/test/smali/conditions/TestIfCodeStyle.smali
+354
-0
jadx-core/src/test/smali/trycatch/TestLoopInTryCatch.smali
jadx-core/src/test/smali/trycatch/TestLoopInTryCatch.smali
+1
-1
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/sections/debuginfo/DebugInfoParser.java
...plugins/input/dex/sections/debuginfo/DebugInfoParser.java
+11
-22
未找到文件。
jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java
浏览文件 @
a71b3a71
...
...
@@ -80,6 +80,7 @@ public enum AFlag {
RERUN_SSA_TRANSFORM
,
METHOD_CANDIDATE_FOR_INLINE
,
USE_LINES_HINTS
,
// source lines info in methods can be trusted
DISABLE_BLOCKS_LOCK
,
...
...
jadx-core/src/main/java/jadx/core/dex/regions/conditions/IfCondition.java
浏览文件 @
a71b3a71
...
...
@@ -278,6 +278,16 @@ public final class IfCondition extends AttrNode {
return
list
;
}
public
int
getSourceLine
()
{
for
(
InsnNode
insn
:
collectInsns
())
{
int
line
=
insn
.
getSourceLine
();
if
(
line
!=
0
)
{
return
line
;
}
}
return
0
;
}
@Nullable
public
InsnNode
getFirstInsn
()
{
if
(
mode
==
Mode
.
COMPARE
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/debuginfo/DebugInfoAttachVisitor.java
浏览文件 @
a71b3a71
package
jadx.core.dex.visitors.debuginfo
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
jadx.api.plugins.input.data.IDebugInfo
;
import
jadx.api.plugins.input.data.ILocalVar
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.nodes.LocalVarsDebugInfoAttr
;
import
jadx.core.dex.attributes.nodes.RegDebugInfoAttr
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.RegisterArg
;
...
...
@@ -17,6 +20,7 @@ import jadx.core.dex.visitors.AbstractVisitor;
import
jadx.core.dex.visitors.JadxVisitor
;
import
jadx.core.dex.visitors.blocks.BlockSplitter
;
import
jadx.core.dex.visitors.ssa.SSATransform
;
import
jadx.core.utils.ListUtils
;
import
jadx.core.utils.exceptions.JadxException
;
@JadxVisitor
(
...
...
@@ -52,17 +56,30 @@ public class DebugInfoAttachVisitor extends AbstractVisitor {
if
(
lineMapping
.
isEmpty
())
{
return
;
}
Map
<
Integer
,
Integer
>
linesStat
=
new
HashMap
<>();
// count repeating lines
for
(
Map
.
Entry
<
Integer
,
Integer
>
entry
:
lineMapping
.
entrySet
())
{
try
{
Integer
offset
=
entry
.
getKey
();
InsnNode
insn
=
insnArr
[
offset
];
if
(
insn
!=
null
)
{
insn
.
setSourceLine
(
entry
.
getValue
());
int
line
=
entry
.
getValue
();
insn
.
setSourceLine
(
line
);
if
(
insn
.
getType
()
!=
InsnType
.
NOP
)
{
linesStat
.
merge
(
line
,
1
,
(
v
,
one
)
->
v
+
1
);
}
}
}
catch
(
Exception
e
)
{
mth
.
addWarnComment
(
"Error attach source line"
,
e
);
}
}
// 3 here is allowed maximum for lines repeat,
// can occur in indexed 'for' loops (3 instructions with same line)
List
<
Map
.
Entry
<
Integer
,
Integer
>>
repeatingLines
=
ListUtils
.
filter
(
linesStat
.
entrySet
(),
p
->
p
.
getValue
()
>
3
);
if
(
repeatingLines
.
isEmpty
())
{
mth
.
add
(
AFlag
.
USE_LINES_HINTS
);
}
else
{
mth
.
addDebugComment
(
"Don't trust debug lines info. Repeating lines: "
+
repeatingLines
);
}
}
private
void
attachDebugInfo
(
MethodNode
mth
,
List
<
ILocalVar
>
localVars
,
InsnNode
[]
insnArr
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfRegionVisitor.java
浏览文件 @
a71b3a71
...
...
@@ -38,47 +38,74 @@ public class IfRegionVisitor extends AbstractVisitor {
public
boolean
enterRegion
(
MethodNode
mth
,
IRegion
region
)
{
if
(
region
instanceof
IfRegion
)
{
IfRegion
ifRegion
=
(
IfRegion
)
region
;
simplifyIfCondition
(
ifRegion
);
moveReturnToThenBlock
(
mth
,
ifRegion
);
moveBreakToThenBlock
(
ifRegion
);
markElseIfChains
(
ifRegion
);
orderBranches
(
mth
,
ifRegion
);
markElseIfChains
(
mth
,
ifRegion
);
}
return
true
;
}
}
private
static
class
RemoveRedundantElseVisitor
implements
IRegionIterativeVisitor
{
@Override
public
boolean
visitRegion
(
MethodNode
mth
,
IRegion
region
)
{
if
(
region
instanceof
IfRegion
)
{
return
removeRedundantElseBlock
(
mth
,
(
IfRegion
)
region
);
@SuppressWarnings
(
"UnnecessaryReturnStatement"
)
private
static
void
orderBranches
(
MethodNode
mth
,
IfRegion
ifRegion
)
{
if
(
RegionUtils
.
isEmpty
(
ifRegion
.
getElseRegion
()))
{
return
;
}
if
(
RegionUtils
.
isEmpty
(
ifRegion
.
getThenRegion
()))
{
invertIfRegion
(
ifRegion
);
return
;
}
if
(
mth
.
contains
(
AFlag
.
USE_LINES_HINTS
))
{
int
thenLine
=
RegionUtils
.
getFirstSourceLine
(
ifRegion
.
getThenRegion
());
int
elseLine
=
RegionUtils
.
getFirstSourceLine
(
ifRegion
.
getElseRegion
());
if
(
thenLine
!=
0
&&
elseLine
!=
0
)
{
if
(
thenLine
>
elseLine
)
{
invertIfRegion
(
ifRegion
);
}
return
;
}
return
false
;
}
}
private
static
void
simplifyIfCondition
(
IfRegion
ifRegion
)
{
if
(
ifRegion
.
simplifyCondition
())
{
IfCondition
condition
=
ifRegion
.
getCondition
();
if
(
condition
.
getMode
()
==
Mode
.
NOT
)
{
if
(
condition
!=
null
&&
condition
.
getMode
()
==
Mode
.
NOT
)
{
invertIfRegion
(
ifRegion
);
}
}
IContainer
elseRegion
=
ifRegion
.
getElseRegion
();
if
(
elseRegion
==
null
||
RegionUtils
.
isEmpty
(
elseRegion
))
{
int
thenSize
=
insnsCount
(
ifRegion
.
getThenRegion
());
int
elseSize
=
insnsCount
(
ifRegion
.
getElseRegion
());
if
(
isSimpleExitBlock
(
mth
,
ifRegion
.
getElseRegion
()))
{
if
(
isSimpleExitBlock
(
mth
,
ifRegion
.
getThenRegion
()))
{
if
(
elseSize
<
thenSize
)
{
invertIfRegion
(
ifRegion
);
return
;
}
}
boolean
lastRegion
=
ifRegion
==
RegionUtils
.
getLastRegion
(
mth
.
getRegion
());
if
(
elseSize
==
1
&&
lastRegion
&&
mth
.
isVoidReturn
())
{
// single return at method end will be removed later
return
;
}
if
(!
lastRegion
)
{
invertIfRegion
(
ifRegion
);
}
return
;
}
boolean
thenIsEmpty
=
RegionUtils
.
isEmpty
(
ifRegion
.
getThenRegion
());
if
(
thenIsEmpty
||
hasSimpleReturnBlock
(
ifRegion
.
getThenRegion
()))
{
boolean
thenExit
=
RegionUtils
.
hasExitBlock
(
ifRegion
.
getThenRegion
());
boolean
elseExit
=
RegionUtils
.
hasExitBlock
(
ifRegion
.
getElseRegion
());
if
(
elseExit
&&
(!
thenExit
||
elseSize
<
thenSize
))
{
invertIfRegion
(
ifRegion
);
return
;
}
if
(!
thenIsEmpty
)
{
// move 'if' from then to make 'else if' chain
if
(
isIfRegion
(
ifRegion
.
getThenRegion
())
&&
!
isIfRegion
(
elseRegion
))
{
invertIfRegion
(
ifRegion
);
}
// move 'if' from 'then' branch to make 'else if' chain
if
(
isIfRegion
(
ifRegion
.
getThenRegion
())
&&
!
isIfRegion
(
ifRegion
.
getElseRegion
())
&&
!
thenExit
)
{
invertIfRegion
(
ifRegion
);
return
;
}
// move 'break' into 'then' branch
if
(
RegionUtils
.
hasBreakInsn
(
ifRegion
.
getElseRegion
()))
{
invertIfRegion
(
ifRegion
);
return
;
}
}
...
...
@@ -88,33 +115,16 @@ public class IfRegionVisitor extends AbstractVisitor {
}
if
(
container
instanceof
IRegion
)
{
List
<
IContainer
>
subBlocks
=
((
IRegion
)
container
).
getSubBlocks
();
if
(
subBlocks
.
size
()
==
1
&&
subBlocks
.
get
(
0
)
instanceof
IfRegion
)
{
return
true
;
}
return
subBlocks
.
size
()
==
1
&&
subBlocks
.
get
(
0
)
instanceof
IfRegion
;
}
return
false
;
}
private
static
void
moveReturnToThenBlock
(
MethodNode
mth
,
IfRegion
ifRegion
)
{
if
(!
mth
.
isVoidReturn
()
&&
hasSimpleReturnBlock
(
ifRegion
.
getElseRegion
())
/* && insnsCount(ifRegion.getThenRegion()) < 2 */
)
{
invertIfRegion
(
ifRegion
);
}
}
private
static
void
moveBreakToThenBlock
(
IfRegion
ifRegion
)
{
if
(
ifRegion
.
getElseRegion
()
!=
null
&&
RegionUtils
.
hasBreakInsn
(
ifRegion
.
getElseRegion
()))
{
invertIfRegion
(
ifRegion
);
}
}
/**
* Mark if-else-if chains
*/
private
static
void
markElseIfChains
(
IfRegion
ifRegion
)
{
if
(
hasSimpleReturnBlock
(
ifRegion
.
getThenRegion
()))
{
private
static
void
markElseIfChains
(
MethodNode
mth
,
IfRegion
ifRegion
)
{
if
(
isSimpleExitBlock
(
mth
,
ifRegion
.
getThenRegion
()))
{
return
;
}
IContainer
elsRegion
=
ifRegion
.
getElseRegion
();
...
...
@@ -127,6 +137,16 @@ public class IfRegionVisitor extends AbstractVisitor {
}
}
private
static
class
RemoveRedundantElseVisitor
implements
IRegionIterativeVisitor
{
@Override
public
boolean
visitRegion
(
MethodNode
mth
,
IRegion
region
)
{
if
(
region
instanceof
IfRegion
)
{
return
removeRedundantElseBlock
(
mth
,
(
IfRegion
)
region
);
}
return
false
;
}
}
private
static
boolean
removeRedundantElseBlock
(
MethodNode
mth
,
IfRegion
ifRegion
)
{
if
(
ifRegion
.
getElseRegion
()
==
null
||
ifRegion
.
contains
(
AFlag
.
ELSE_IF_CHAIN
)
...
...
@@ -162,16 +182,16 @@ public class IfRegionVisitor extends AbstractVisitor {
}
}
private
static
boolean
hasSimpleReturnBlock
(
IContainer
region
)
{
if
(
region
==
null
)
{
private
static
boolean
isSimpleExitBlock
(
MethodNode
mth
,
IContainer
container
)
{
if
(
container
==
null
)
{
return
false
;
}
if
(
region
.
contains
(
AFlag
.
RETURN
))
{
if
(
container
.
contains
(
AFlag
.
RETURN
)
||
RegionUtils
.
isExitBlock
(
mth
,
container
))
{
return
true
;
}
if
(
region
instanceof
IRegion
)
{
List
<
IContainer
>
subBlocks
=
((
IRegion
)
region
).
getSubBlocks
();
return
subBlocks
.
size
()
==
1
&&
subBlocks
.
get
(
0
).
contains
(
AFlag
.
RETURN
);
if
(
container
instanceof
IRegion
)
{
List
<
IContainer
>
subBlocks
=
((
IRegion
)
container
).
getSubBlocks
();
return
subBlocks
.
size
()
==
1
&&
RegionUtils
.
isExitBlock
(
mth
,
subBlocks
.
get
(
0
)
);
}
return
false
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/TernaryMod.java
浏览文件 @
a71b3a71
...
...
@@ -93,7 +93,8 @@ public class TernaryMod extends AbstractRegionVisitor implements IRegionIterativ
InsnNode
thenInsn
=
tb
.
getInstructions
().
get
(
0
);
InsnNode
elseInsn
=
eb
.
getInstructions
().
get
(
0
);
if
(
thenInsn
.
getSourceLine
()
!=
elseInsn
.
getSourceLine
())
{
if
(
mth
.
contains
(
AFlag
.
USE_LINES_HINTS
)
&&
thenInsn
.
getSourceLine
()
!=
elseInsn
.
getSourceLine
())
{
if
(
thenInsn
.
getSourceLine
()
!=
0
&&
elseInsn
.
getSourceLine
()
!=
0
)
{
// sometimes source lines incorrect
if
(!
checkLineStats
(
thenInsn
,
elseInsn
))
{
...
...
@@ -134,6 +135,8 @@ public class TernaryMod extends AbstractRegionVisitor implements IRegionIterativ
InsnArg
thenArg
=
InsnArg
.
wrapInsnIntoArg
(
thenInsn
);
InsnArg
elseArg
=
InsnArg
.
wrapInsnIntoArg
(
elseInsn
);
TernaryInsn
ternInsn
=
new
TernaryInsn
(
ifRegion
.
getCondition
(),
resArg
,
thenArg
,
elseArg
);
int
branchLine
=
Math
.
max
(
thenInsn
.
getSourceLine
(),
elseInsn
.
getSourceLine
());
ternInsn
.
setSourceLine
(
Math
.
max
(
ifRegion
.
getSourceLine
(),
branchLine
));
InsnRemover
.
unbindResult
(
mth
,
elseInsn
);
...
...
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
浏览文件 @
a71b3a71
...
...
@@ -182,6 +182,16 @@ public class BlockUtils {
return
null
;
}
public
static
int
getFirstSourceLine
(
IBlock
block
)
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
int
line
=
insn
.
getSourceLine
();
if
(
line
!=
0
)
{
return
line
;
}
}
return
0
;
}
@Nullable
public
static
InsnNode
getFirstInsn
(
@Nullable
IBlock
block
)
{
if
(
block
==
null
)
{
...
...
@@ -207,11 +217,22 @@ public class BlockUtils {
}
public
static
boolean
isExitBlock
(
MethodNode
mth
,
BlockNode
block
)
{
BlockNode
exitBlock
=
mth
.
getExitBlock
();
if
(
block
==
exitBlock
)
{
if
(
block
==
mth
.
getExitBlock
())
{
return
true
;
}
return
exitBlock
.
getPredecessors
().
contains
(
block
);
return
isExitBlock
(
block
);
}
public
static
boolean
isExitBlock
(
BlockNode
block
)
{
List
<
BlockNode
>
successors
=
block
.
getSuccessors
();
if
(
successors
.
isEmpty
())
{
return
true
;
}
if
(
successors
.
size
()
==
1
)
{
BlockNode
next
=
successors
.
get
(
0
);
return
next
.
getSuccessors
().
isEmpty
();
}
return
false
;
}
public
static
boolean
containsExitInsn
(
IBlock
block
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
浏览文件 @
a71b3a71
...
...
@@ -16,6 +16,7 @@ import jadx.core.dex.instructions.InsnType;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.IBlock
;
import
jadx.core.dex.nodes.IBranchRegion
;
import
jadx.core.dex.nodes.IConditionRegion
;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.InsnNode
;
...
...
@@ -52,6 +53,7 @@ public class RegionUtils {
throw
new
JadxRuntimeException
(
unknownContainerType
(
container
));
}
@Nullable
public
static
InsnNode
getFirstInsn
(
IContainer
container
)
{
if
(
container
instanceof
IBlock
)
{
IBlock
block
=
(
IBlock
)
container
;
...
...
@@ -74,6 +76,37 @@ public class RegionUtils {
}
}
public
static
int
getFirstSourceLine
(
IContainer
container
)
{
if
(
container
instanceof
IBlock
)
{
return
BlockUtils
.
getFirstSourceLine
((
IBlock
)
container
);
}
if
(
container
instanceof
IConditionRegion
)
{
return
((
IConditionRegion
)
container
).
getConditionSourceLine
();
}
if
(
container
instanceof
IBranchRegion
)
{
IBranchRegion
branchRegion
=
(
IBranchRegion
)
container
;
return
getFirstSourceLine
(
branchRegion
.
getBranches
());
}
if
(
container
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
container
;
return
getFirstSourceLine
(
region
.
getSubBlocks
());
}
return
0
;
}
private
static
int
getFirstSourceLine
(
List
<
IContainer
>
containers
)
{
if
(
containers
.
isEmpty
())
{
return
0
;
}
for
(
IContainer
container
:
containers
)
{
int
line
=
getFirstSourceLine
(
container
);
if
(
line
!=
0
)
{
return
line
;
}
}
return
0
;
}
public
static
InsnNode
getLastInsn
(
IContainer
container
)
{
if
(
container
instanceof
IBlock
)
{
IBlock
block
=
(
IBlock
)
container
;
...
...
@@ -112,31 +145,58 @@ public class RegionUtils {
}
}
@Nullable
public
static
IContainer
getLastRegion
(
@Nullable
IContainer
container
)
{
if
(
container
==
null
)
{
return
null
;
}
if
(
container
instanceof
IBlock
||
container
instanceof
IBranchRegion
)
{
return
container
;
}
if
(
container
instanceof
IRegion
)
{
return
getLastRegion
(
Utils
.
last
(((
IRegion
)
container
).
getSubBlocks
()));
}
throw
new
JadxRuntimeException
(
unknownContainerType
(
container
));
}
public
static
boolean
isExitBlock
(
MethodNode
mth
,
IContainer
container
)
{
if
(
container
instanceof
BlockNode
)
{
return
BlockUtils
.
isExitBlock
(
mth
,
(
BlockNode
)
container
);
}
return
false
;
}
/**
* Return true if last block in region has no successors or jump out insn (return or break)
*/
public
static
boolean
hasExitBlock
(
IContainer
container
)
{
if
(
container
==
null
)
{
return
false
;
}
return
hasExitBlock
(
container
,
container
);
}
private
static
boolean
hasExitBlock
(
IContainer
rootContainer
,
IContainer
container
)
{
if
(
container
instanceof
BlockNode
)
{
BlockNode
blockNode
=
(
BlockNode
)
container
;
if
(
blockNode
.
getSuccessors
().
isEmpty
(
))
{
if
(
BlockUtils
.
isExitBlock
(
blockNode
))
{
return
true
;
}
return
isInsnExitContainer
(
rootContainer
,
(
IBlock
)
container
);
}
else
if
(
container
instanceof
IBranchRegion
)
{
return
false
;
}
else
if
(
container
instanceof
IBlock
)
{
}
if
(
container
instanceof
IBranchRegion
)
{
IBranchRegion
branchRegion
=
(
IBranchRegion
)
container
;
return
ListUtils
.
allMatch
(
branchRegion
.
getBranches
(),
RegionUtils:
:
hasExitBlock
);
}
if
(
container
instanceof
IBlock
)
{
return
isInsnExitContainer
(
rootContainer
,
(
IBlock
)
container
);
}
else
if
(
container
instanceof
IRegion
)
{
}
if
(
container
instanceof
IRegion
)
{
List
<
IContainer
>
blocks
=
((
IRegion
)
container
).
getSubBlocks
();
return
!
blocks
.
isEmpty
()
&&
hasExitBlock
(
rootContainer
,
blocks
.
get
(
blocks
.
size
()
-
1
));
}
else
{
throw
new
JadxRuntimeException
(
unknownContainerType
(
container
));
}
throw
new
JadxRuntimeException
(
unknownContainerType
(
container
));
}
private
static
boolean
isInsnExitContainer
(
IContainer
rootContainer
,
IBlock
block
)
{
...
...
@@ -192,17 +252,25 @@ public class RegionUtils {
public
static
int
insnsCount
(
IContainer
container
)
{
if
(
container
instanceof
IBlock
)
{
return
((
IBlock
)
container
).
getInstructions
().
size
();
}
else
if
(
container
instanceof
IRegion
)
{
List
<
InsnNode
>
insnList
=
((
IBlock
)
container
).
getInstructions
();
int
count
=
0
;
for
(
InsnNode
insn
:
insnList
)
{
if
(
insn
.
contains
(
AFlag
.
DONT_GENERATE
))
{
continue
;
}
count
++;
}
return
count
;
}
if
(
container
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
container
;
int
count
=
0
;
for
(
IContainer
block
:
region
.
getSubBlocks
())
{
count
+=
insnsCount
(
block
);
}
return
count
;
}
else
{
throw
new
JadxRuntimeException
(
unknownContainerType
(
container
));
}
throw
new
JadxRuntimeException
(
unknownContainerType
(
container
));
}
public
static
boolean
isEmpty
(
IContainer
container
)
{
...
...
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
浏览文件 @
a71b3a71
...
...
@@ -150,9 +150,9 @@ public abstract class IntegrationTest extends TestUtils {
close
(
decompiledCompiler
);
}
private
void
close
(
Closeable
clo
ase
ble
)
throws
IOException
{
if
(
clo
ase
ble
!=
null
)
{
clo
ase
ble
.
close
();
private
void
close
(
Closeable
clo
sea
ble
)
throws
IOException
{
if
(
clo
sea
ble
!=
null
)
{
clo
sea
ble
.
close
();
}
}
...
...
jadx-core/src/test/java/jadx/tests/integration/conditions/TestBitwiseAnd.java
浏览文件 @
a71b3a71
...
...
@@ -8,6 +8,7 @@ import jadx.tests.api.IntegrationTest;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
@SuppressWarnings
({
"PointlessBooleanExpression"
,
"unused"
})
public
class
TestBitwiseAnd
extends
IntegrationTest
{
public
static
class
TestCls
{
...
...
jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions14.java
浏览文件 @
a71b3a71
...
...
@@ -10,6 +10,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
public
class
TestConditions14
extends
IntegrationTest
{
@SuppressWarnings
({
"EqualsReplaceableByObjectsCall"
,
"ConstantConditions"
})
public
static
class
TestCls
{
public
static
boolean
test
(
Object
a
,
Object
b
)
{
...
...
jadx-core/src/test/java/jadx/tests/integration/conditions/TestIfCodeStyle.java
0 → 100644
浏览文件 @
a71b3a71
package
jadx.tests.integration.conditions
;
import
org.junit.jupiter.api.Test
;
import
jadx.tests.api.SmaliTest
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
/**
* Issue #1455
*/
public
class
TestIfCodeStyle
extends
SmaliTest
{
@SuppressWarnings
({
"ConstantConditions"
,
"FieldCanBeLocal"
,
"unused"
})
public
static
class
TestCls
{
private
String
moduleName
;
private
String
modulePath
;
private
String
preinstalledModulePath
;
private
long
versionCode
;
private
String
versionName
;
private
boolean
isFactory
;
private
boolean
isActive
;
public
void
test
(
Parcel
parcel
)
{
int
startPos
=
parcel
.
dataPosition
();
int
size
=
parcel
.
readInt
();
if
(
size
<
0
)
{
if
(
startPos
>
Integer
.
MAX_VALUE
-
size
)
{
throw
new
RuntimeException
(
"Overflow in the size of parcelable"
);
}
parcel
.
setDataPosition
(
startPos
+
size
);
return
;
}
try
{
if
(
parcel
.
dataPosition
()
-
startPos
>=
size
)
{
if
(
startPos
>
Integer
.
MAX_VALUE
-
size
)
{
throw
new
RuntimeException
(
"Overflow in the size of parcelable"
);
}
parcel
.
setDataPosition
(
startPos
+
size
);
return
;
}
this
.
moduleName
=
parcel
.
readString
();
if
(
parcel
.
dataPosition
()
-
startPos
>=
size
)
{
if
(
startPos
>
Integer
.
MAX_VALUE
-
size
)
{
throw
new
RuntimeException
(
"Overflow in the size of parcelable"
);
}
parcel
.
setDataPosition
(
startPos
+
size
);
return
;
}
this
.
modulePath
=
parcel
.
readString
();
if
(
parcel
.
dataPosition
()
-
startPos
>=
size
)
{
if
(
startPos
>
Integer
.
MAX_VALUE
-
size
)
{
throw
new
RuntimeException
(
"Overflow in the size of parcelable"
);
}
parcel
.
setDataPosition
(
startPos
+
size
);
return
;
}
this
.
preinstalledModulePath
=
parcel
.
readString
();
if
(
parcel
.
dataPosition
()
-
startPos
>=
size
)
{
if
(
startPos
>
Integer
.
MAX_VALUE
-
size
)
{
throw
new
RuntimeException
(
"Overflow in the size of parcelable"
);
}
parcel
.
setDataPosition
(
startPos
+
size
);
return
;
}
this
.
versionCode
=
parcel
.
readLong
();
if
(
parcel
.
dataPosition
()
-
startPos
>=
size
)
{
if
(
startPos
>
Integer
.
MAX_VALUE
-
size
)
{
throw
new
RuntimeException
(
"Overflow in the size of parcelable"
);
}
parcel
.
setDataPosition
(
startPos
+
size
);
return
;
}
this
.
versionName
=
parcel
.
readString
();
if
(
parcel
.
dataPosition
()
-
startPos
>=
size
)
{
if
(
startPos
>
Integer
.
MAX_VALUE
-
size
)
{
throw
new
RuntimeException
(
"Overflow in the size of parcelable"
);
}
parcel
.
setDataPosition
(
startPos
+
size
);
return
;
}
this
.
isFactory
=
parcel
.
readInt
()
!=
0
;
if
(
parcel
.
dataPosition
()
-
startPos
>=
size
)
{
if
(
startPos
>
Integer
.
MAX_VALUE
-
size
)
{
throw
new
RuntimeException
(
"Overflow in the size of parcelable"
);
}
parcel
.
setDataPosition
(
startPos
+
size
);
return
;
}
this
.
isActive
=
parcel
.
readInt
()
!=
0
;
if
(
startPos
>
Integer
.
MAX_VALUE
-
size
)
{
throw
new
RuntimeException
(
"Overflow in the size of parcelable"
);
}
parcel
.
setDataPosition
(
startPos
+
size
);
}
catch
(
Throwable
e
)
{
if
(
startPos
<=
Integer
.
MAX_VALUE
-
size
)
{
parcel
.
setDataPosition
(
startPos
+
size
);
throw
e
;
}
throw
new
RuntimeException
(
"Overflow in the size of parcelable"
);
}
}
private
static
class
Parcel
{
public
void
setDataPosition
(
int
i
)
{
}
public
int
dataPosition
()
{
return
0
;
}
public
int
readInt
()
{
return
0
;
}
public
String
readString
()
{
return
null
;
}
public
long
readLong
()
{
return
0
;
}
}
}
@Test
public
void
test
()
{
noDebugInfo
();
assertThat
(
getClassNode
(
TestCls
.
class
))
.
code
()
.
doesNotContain
(
"else"
)
.
countString
(
8
,
"return;"
)
.
containsLines
(
2
,
"if (readInt < 0) {"
,
indent
()
+
"if (dataPosition > Integer.MAX_VALUE - readInt) {"
,
indent
(
2
)
+
"throw new RuntimeException(\"Overflow in the size of parcelable\");"
,
indent
()
+
"}"
,
indent
()
+
"parcel.setDataPosition(dataPosition + readInt);"
,
indent
()
+
"return;"
,
"}"
);
}
@Test
public
void
testSmali
()
{
disableCompilation
();
assertThat
(
getClassNodeFromSmali
())
.
code
()
.
doesNotContain
(
"else"
)
.
countString
(
8
,
"return;"
)
.
containsLines
(
2
,
"if (_aidl_parcelable_size < 0) {"
,
indent
()
+
"if (_aidl_start_pos > Integer.MAX_VALUE - _aidl_parcelable_size) {"
,
indent
(
2
)
+
"throw new RuntimeException(\"Overflow in the size of parcelable\");"
,
indent
()
+
"}"
,
indent
()
+
"_aidl_parcel.setDataPosition(_aidl_start_pos + _aidl_parcelable_size);"
,
indent
()
+
"return;"
,
"}"
);
}
}
jadx-core/src/test/java/jadx/tests/integration/debuginfo/TestLineNumbers2.java
浏览文件 @
a71b3a71
...
...
@@ -2,10 +2,10 @@ package jadx.tests.integration.debuginfo;
import
java.lang.ref.WeakReference
;
import
org.junit.jupiter.api.Test
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
jadx.tests.api.extensions.profiles.TestProfile
;
import
jadx.tests.api.extensions.profiles.TestWithProfiles
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertEquals
;
...
...
@@ -32,17 +32,16 @@ public class TestLineNumbers2 extends IntegrationTest {
}
}
@Test
@Test
WithProfiles
({
TestProfile
.
DX_J8
,
TestProfile
.
JAVA8
})
public
void
test
()
{
printLineNumbers
();
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
linesMapStr
=
cls
.
getCode
().
getLineMapping
().
toString
();
if
(
isJavaInput
())
{
assertEquals
(
"{6=16, 9=17, 12=21, 13=22, 14=23, 1
6=25, 18=27, 21=30
}"
,
linesMapStr
);
assertEquals
(
"{6=16, 9=17, 12=21, 13=22, 14=23, 1
5=24, 16=25, 18=27, 21=30, 22=31
}"
,
linesMapStr
);
}
else
{
// TODO: invert condition to match source lines
assertEquals
(
"{6=16, 9=17, 12=21, 13=22, 14=23, 15=27, 17=24, 18=25, 19=27, 22=30, 23=31}"
,
linesMapStr
);
assertEquals
(
"{6=16, 9=17, 12=21, 13=22, 14=23, 15=24, 16=25, 17=27, 19=27, 22=30, 23=31}"
,
linesMapStr
);
}
}
}
jadx-core/src/test/java/jadx/tests/integration/loops/TestSequentialLoops.java
浏览文件 @
a71b3a71
...
...
@@ -2,14 +2,9 @@ package jadx.tests.integration.loops;
import
org.junit.jupiter.api.Test
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
countString
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
hamcrest
.
CoreMatchers
.
not
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestSequentialLoops
extends
IntegrationTest
{
...
...
@@ -35,13 +30,10 @@ public class TestSequentialLoops extends IntegrationTest {
@Test
public
void
test
()
{
disableCompilation
();
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
countString
(
2
,
"while ("
));
assertThat
(
code
,
containsOne
(
"break;"
));
assertThat
(
code
,
containsOne
(
"return c;"
));
assertThat
(
code
,
not
(
containsString
(
"else"
)));
assertThat
(
getClassNode
(
TestCls
.
class
))
.
code
()
.
countString
(
2
,
"while ("
)
.
containsOne
(
"break;"
)
.
containsOne
(
"return c;"
);
}
}
jadx-core/src/test/java/jadx/tests/integration/trycatch/TestLoopInTryCatch.java
浏览文件 @
a71b3a71
...
...
@@ -23,7 +23,8 @@ public class TestLoopInTryCatch extends SmaliTest {
" break;"
,
" }"
,
"}"
,
"if (i == 1) {"
,
"if (i != 1) {"
,
" getI();"
,
"}"
),
c
->
c
.
containsLines
(
2
,
"int i;"
,
...
...
@@ -37,7 +38,8 @@ public class TestLoopInTryCatch extends SmaliTest {
" return;"
,
" }"
,
"}"
,
"if (i == 1) {"
,
"if (i != 1) {"
,
" getI();"
,
"}"
));
}
}
jadx-core/src/test/smali/conditions/TestIfCodeStyle.smali
0 → 100644
浏览文件 @
a71b3a71
.class public Lconditions/TestIfCodeStyle;
.super Ljava/lang/Object;
.implements Landroid/os/Parcelable;
.field public isActive:Z
.field public isFactory:Z
.field public moduleName:Ljava/lang/String;
.field public modulePath:Ljava/lang/String;
.field public preinstalledModulePath:Ljava/lang/String;
.field public versionCode:J
.field public versionName:Ljava/lang/String;
.method public final readFromParcel(Landroid/os/Parcel;)V
.registers 9
.param p1, "_aidl_parcel" # Landroid/os/Parcel;
.line 44
invoke-virtual {p1}, Landroid/os/Parcel;->dataPosition()I
move-result v0
.line 45
.local v0, "_aidl_start_pos":I
invoke-virtual {p1}, Landroid/os/Parcel;->readInt()I
move-result v1
.line 47
.local v1, "_aidl_parcelable_size":I
const-string v2, "Overflow in the size of parcelable"
const v3, 0x7fffffff
if-gez v1, :cond_1e
.line 63
sub-int/2addr v3, v1
if-gt v0, v3, :cond_18
.line 66
add-int v2, v0, v1
invoke-virtual {p1, v2}, Landroid/os/Parcel;->setDataPosition(I)V
.line 47
return-void
.line 64
:cond_18
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
throw v3
.line 48
:cond_1e
:try_start_1e
invoke-virtual {p1}, Landroid/os/Parcel;->dataPosition()I
move-result v4
:try_end_22
.catchall {:try_start_1e .. :try_end_22} :catchall_fd
sub-int/2addr v4, v0
if-lt v4, v1, :cond_34
.line 63
sub-int/2addr v3, v1
if-gt v0, v3, :cond_2e
.line 66
add-int v2, v0, v1
invoke-virtual {p1, v2}, Landroid/os/Parcel;->setDataPosition(I)V
.line 48
return-void
.line 64
:cond_2e
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
throw v3
.line 49
:cond_34
:try_start_34
invoke-virtual {p1}, Landroid/os/Parcel;->readString()Ljava/lang/String;
move-result-object v4
iput-object v4, p0, Lconditions/TestIfCodeStyle;->moduleName:Ljava/lang/String;
.line 50
invoke-virtual {p1}, Landroid/os/Parcel;->dataPosition()I
move-result v4
:try_end_3e
.catchall {:try_start_34 .. :try_end_3e} :catchall_fd
sub-int/2addr v4, v0
if-lt v4, v1, :cond_50
.line 63
sub-int/2addr v3, v1
if-gt v0, v3, :cond_4a
.line 66
add-int v2, v0, v1
invoke-virtual {p1, v2}, Landroid/os/Parcel;->setDataPosition(I)V
.line 50
return-void
.line 64
:cond_4a
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
throw v3
.line 51
:cond_50
:try_start_50
invoke-virtual {p1}, Landroid/os/Parcel;->readString()Ljava/lang/String;
move-result-object v4
iput-object v4, p0, Lconditions/TestIfCodeStyle;->modulePath:Ljava/lang/String;
.line 52
invoke-virtual {p1}, Landroid/os/Parcel;->dataPosition()I
move-result v4
:try_end_5a
.catchall {:try_start_50 .. :try_end_5a} :catchall_fd
sub-int/2addr v4, v0
if-lt v4, v1, :cond_6c
.line 63
sub-int/2addr v3, v1
if-gt v0, v3, :cond_66
.line 66
add-int v2, v0, v1
invoke-virtual {p1, v2}, Landroid/os/Parcel;->setDataPosition(I)V
.line 52
return-void
.line 64
:cond_66
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
throw v3
.line 53
:cond_6c
:try_start_6c
invoke-virtual {p1}, Landroid/os/Parcel;->readString()Ljava/lang/String;
move-result-object v4
iput-object v4, p0, Lconditions/TestIfCodeStyle;->preinstalledModulePath:Ljava/lang/String;
.line 54
invoke-virtual {p1}, Landroid/os/Parcel;->dataPosition()I
move-result v4
:try_end_76
.catchall {:try_start_6c .. :try_end_76} :catchall_fd
sub-int/2addr v4, v0
if-lt v4, v1, :cond_88
.line 63
sub-int/2addr v3, v1
if-gt v0, v3, :cond_82
.line 66
add-int v2, v0, v1
invoke-virtual {p1, v2}, Landroid/os/Parcel;->setDataPosition(I)V
.line 54
return-void
.line 64
:cond_82
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
throw v3
.line 55
:cond_88
:try_start_88
invoke-virtual {p1}, Landroid/os/Parcel;->readLong()J
move-result-wide v4
iput-wide v4, p0, Lconditions/TestIfCodeStyle;->versionCode:J
.line 56
invoke-virtual {p1}, Landroid/os/Parcel;->dataPosition()I
move-result v4
:try_end_92
.catchall {:try_start_88 .. :try_end_92} :catchall_fd
sub-int/2addr v4, v0
if-lt v4, v1, :cond_a4
.line 63
sub-int/2addr v3, v1
if-gt v0, v3, :cond_9e
.line 66
add-int v2, v0, v1
invoke-virtual {p1, v2}, Landroid/os/Parcel;->setDataPosition(I)V
.line 56
return-void
.line 64
:cond_9e
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
throw v3
.line 57
:cond_a4
:try_start_a4
invoke-virtual {p1}, Landroid/os/Parcel;->readString()Ljava/lang/String;
move-result-object v4
iput-object v4, p0, Lconditions/TestIfCodeStyle;->versionName:Ljava/lang/String;
.line 58
invoke-virtual {p1}, Landroid/os/Parcel;->dataPosition()I
move-result v4
:try_end_ae
.catchall {:try_start_a4 .. :try_end_ae} :catchall_fd
sub-int/2addr v4, v0
if-lt v4, v1, :cond_c0
.line 63
sub-int/2addr v3, v1
if-gt v0, v3, :cond_ba
.line 66
add-int v2, v0, v1
invoke-virtual {p1, v2}, Landroid/os/Parcel;->setDataPosition(I)V
.line 58
return-void
.line 64
:cond_ba
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
throw v3
.line 59
:cond_c0
:try_start_c0
invoke-virtual {p1}, Landroid/os/Parcel;->readInt()I
move-result v4
const/4 v5, 0x1
const/4 v6, 0x0
if-eqz v4, :cond_ca
move v4, v5
goto :goto_cb
:cond_ca
move v4, v6
:goto_cb
iput-boolean v4, p0, Lconditions/TestIfCodeStyle;->isFactory:Z
.line 60
invoke-virtual {p1}, Landroid/os/Parcel;->dataPosition()I
move-result v4
:try_end_d1
.catchall {:try_start_c0 .. :try_end_d1} :catchall_fd
sub-int/2addr v4, v0
if-lt v4, v1, :cond_e3
.line 63
sub-int/2addr v3, v1
if-gt v0, v3, :cond_dd
.line 66
add-int v2, v0, v1
invoke-virtual {p1, v2}, Landroid/os/Parcel;->setDataPosition(I)V
.line 60
return-void
.line 64
:cond_dd
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
throw v3
.line 61
:cond_e3
:try_start_e3
invoke-virtual {p1}, Landroid/os/Parcel;->readInt()I
move-result v4
if-eqz v4, :cond_ea
goto :goto_eb
:cond_ea
move v5, v6
:goto_eb
iput-boolean v5, p0, Lconditions/TestIfCodeStyle;->isActive:Z
:try_end_ed
.catchall {:try_start_e3 .. :try_end_ed} :catchall_fd
.line 63
sub-int/2addr v3, v1
if-gt v0, v3, :cond_f7
.line 66
add-int v2, v0, v1
invoke-virtual {p1, v2}, Landroid/os/Parcel;->setDataPosition(I)V
.line 67
nop
.line 68
return-void
.line 64
:cond_f7
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
throw v3
.line 63
:catchall_fd
move-exception v4
sub-int/2addr v3, v1
if-le v0, v3, :cond_107
.line 64
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/String;)V
throw v3
.line 66
:cond_107
add-int v2, v0, v1
invoke-virtual {p1, v2}, Landroid/os/Parcel;->setDataPosition(I)V
.line 67
throw v4
.end method
jadx-core/src/test/smali/trycatch/TestLoopInTryCatch.smali
浏览文件 @
a71b3a71
...
...
@@ -24,7 +24,7 @@
:cond
if-eq v1, v2, :end
invoke-static {}, Ltrycatch/TestLoopInTryCatch;->getI()I
return-void
:try_end
...
...
jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/sections/debuginfo/DebugInfoParser.java
浏览文件 @
a71b3a71
...
...
@@ -101,25 +101,21 @@ public class DebugInfoParser {
varsInfoFound
=
true
;
}
}
// process '0' instruction
addrChange
(-
1
,
1
,
line
);
setLine
(
addr
,
line
);
int
c
=
in
.
readUByte
();
while
(
c
!=
DBG_END_SEQUENCE
)
{
while
(
true
)
{
int
c
=
in
.
readUByte
();
if
(
c
==
DBG_END_SEQUENCE
)
{
break
;
}
switch
(
c
)
{
case
DBG_ADVANCE_PC:
{
int
addrInc
=
in
.
readUleb128
();
addr
=
addrChange
(
addr
,
addrInc
,
line
);
setLine
(
addr
,
line
);
addr
=
addrChange
(
addr
,
addrInc
);
break
;
}
case
DBG_ADVANCE_LINE:
{
line
+=
in
.
readSleb128
();
break
;
}
case
DBG_START_LOCAL:
{
int
regNum
=
in
.
readUleb128
();
int
nameId
=
in
.
readUleb128
()
-
1
;
...
...
@@ -154,30 +150,26 @@ public class DebugInfoParser {
varsInfoFound
=
true
;
break
;
}
case
DBG_SET_PROLOGUE_END:
case
DBG_SET_EPILOGUE_BEGIN:
case
DBG_SET_EPILOGUE_BEGIN:
{
// do nothing
break
;
}
case
DBG_SET_FILE:
{
int
idx
=
in
.
readUleb128
()
-
1
;
this
.
sourceFile
=
ext
.
getString
(
idx
);
break
;
}
default
:
{
int
adjustedOpCode
=
c
-
DBG_FIRST_SPECIAL
;
int
addrInc
=
adjustedOpCode
/
DBG_LINE_RANGE
;
addr
=
addrChange
(
addr
,
addrInc
,
line
);
addr
=
addrChange
(
addr
,
addrInc
);
line
+=
DBG_LINE_BASE
+
adjustedOpCode
%
DBG_LINE_RANGE
;
setLine
(
addr
,
line
);
break
;
}
}
c
=
in
.
readUByte
();
}
if
(
varsInfoFound
)
{
for
(
DexLocalVar
var
:
locals
)
{
if
(
var
!=
null
&&
!
var
.
isEnd
())
{
...
...
@@ -185,14 +177,11 @@ public class DebugInfoParser {
}
}
}
return
new
DebugInfo
(
linesMap
,
resultList
);
}
private
int
addrChange
(
int
addr
,
int
addrInc
,
int
line
)
{
int
newAddr
=
Math
.
min
(
addr
+
addrInc
,
codeSize
-
1
);
setLine
(
newAddr
,
line
);
return
newAddr
;
private
int
addrChange
(
int
addr
,
int
addrInc
)
{
return
Math
.
min
(
addr
+
addrInc
,
codeSize
-
1
);
}
private
void
setLine
(
int
offset
,
int
line
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录