From 119ad2a7902463288e24a44c4273bc8309aa5fc4 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Mon, 7 Oct 2024 16:11:27 -0700 Subject: [PATCH] Fix inline method references --- .../explorer/bytecode/ByteCodeParser.kt | 2 +- .../romainguy/kotlin/explorer/code/Code.kt | 1 + .../kotlin/explorer/code/DataModels.kt | 2 +- .../kotlin/explorer/dex/DexDumpParser.kt | 2 +- .../kotlin/explorer/oat/OatDumpParser.kt | 35 +++++++++++-------- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/bytecode/ByteCodeParser.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/bytecode/ByteCodeParser.kt index d6913af5..2567502f 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/bytecode/ByteCodeParser.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/bytecode/ByteCodeParser.kt @@ -99,7 +99,7 @@ private fun PeekingIterator.readClass(classHeader: String): Class { throw IllegalStateException("Expected '}' but got '${peek()}'") } } - return Class(classHeader, methods) + return Class(classHeader, methods, false) } diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/Code.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/Code.kt index 74f0d2b6..65acc697 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/Code.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/Code.kt @@ -46,6 +46,7 @@ class Code( return buildCode(codeStyle) { val indexedMethods = buildIndexedMethods(classes) classes.forEachIndexed { classIndex, clazz -> + if (clazz.builtIn) return@forEachIndexed startClass(clazz) val notLastClass = classIndex < classes.size - 1 clazz.methods.forEachIndexed { methodIndex, method -> diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/DataModels.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/DataModels.kt index db811738..ca61e583 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/DataModels.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/code/DataModels.kt @@ -79,7 +79,7 @@ enum class ISA(val branchInstructions: ScatterSet, val returnInstruction ) } -data class Class(val header: String, val methods: List) +data class Class(val header: String, val methods: List, val builtIn: Boolean) data class Method(val header: String, val instructionSet: InstructionSet, val index: Int = -1) diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexDumpParser.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexDumpParser.kt index 44688dc6..f1a43a1f 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexDumpParser.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexDumpParser.kt @@ -69,7 +69,7 @@ internal class DexDumpParser { } } } - return Class("class $className", methods) + return Class("class $className", methods, false) } private fun Iterator.readMethod(className: String): Method { diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatDumpParser.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatDumpParser.kt index cfb625fe..8d935e02 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatDumpParser.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatDumpParser.kt @@ -89,9 +89,7 @@ internal class OatDumpParser { jumpRegex: Regex, methodCallRegex: Regex ): Class? { - if (className.matches(BuiltInKotlinClass)) { - return null - } + val builtIn = className.matches(BuiltInKotlinClass) val methods = buildList { while (hasNext()) { val line = peek() @@ -103,28 +101,30 @@ internal class OatDumpParser { val match = MethodRegex.matchEntire(line) if (match != null) { - add(readMethod(match, jumpRegex, methodCallRegex)) + add(readMethod(match, jumpRegex, methodCallRegex, builtIn)) } } } } } - return Class("class $className", methods) + return Class("class $className", methods, builtIn) } private fun PeekingIterator.readMethod( match: MatchResult, jumpRegex: Regex, - methodCallRegex: Regex + methodCallRegex: Regex, + builtIn: Boolean = false ): Method { consumeUntil("DEX CODE:") val methodReferences = readMethodReferences() consumeUntil("CODE:") - val instructions = readNativeInstructions(jumpRegex, methodCallRegex) + val instructions = readNativeInstructions(jumpRegex, methodCallRegex, builtIn) val method = match.getValue("method") val index = match.getValue("methodIndex").toInt() + return Method(method, InstructionSet(isa, instructions, methodReferences), index) } @@ -157,7 +157,8 @@ internal class OatDumpParser { private fun PeekingIterator.readNativeInstructions( jumpRegex: Regex, - methodCallRegex: Regex + methodCallRegex: Regex, + builtIn: Boolean ): List { return buildList { while (hasNext()) { @@ -168,6 +169,7 @@ internal class OatDumpParser { else -> { val match = CodeRegex.matchEntire(next()) if (match != null) { + if (builtIn) continue add( readNativeInstruction( this@readNativeInstructions, @@ -202,13 +204,16 @@ internal class OatDumpParser { // Skip the StackMap line iterator.next() // Check the InlineInfo if present - val methodIndex = DexInlineInfoRegex.matchEntire(iterator.peek()) - if (methodIndex != null) { - callAddress = methodIndex.getValue("callAddress").toInt(16) - methodIndex.getValue("methodIndex").toInt() - } else { - -1 - } + var index = -1 + do { + val methodIndex = DexInlineInfoRegex.matchEntire(iterator.peek()) + if (methodIndex != null) { + callAddress = methodIndex.getValue("callAddress").toInt(16) + index = methodIndex.getValue("methodIndex").toInt() + iterator.next() + } + } while (methodIndex != null) + index } else { -1 }