diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/CodeTextArea.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/CodeTextArea.kt
index 20f771a8..0fb8f8d6 100644
--- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/CodeTextArea.kt
+++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/CodeTextArea.kt
@@ -16,6 +16,7 @@
package dev.romainguy.kotlin.explorer
+import dev.romainguy.kotlin.explorer.jump.JumpDetector
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea
import java.awt.Graphics
import java.awt.Graphics2D
@@ -24,11 +25,9 @@ import javax.swing.event.CaretListener
open class CodeTextArea(
private val explorerState: ExplorerState,
- jumpRegex: Regex,
- addressedRegex: Regex,
+ private val jumpDetector: JumpDetector,
private val lineNumberRegex: Regex?,
) : RSyntaxTextArea() {
- private val jumpDetector = JumpDetector(jumpRegex, addressedRegex)
private var jumpOffsets: JumpOffsets? = null
private var fullText = ""
@@ -114,17 +113,6 @@ open class CodeTextArea(
} ?: this
private data class JumpOffsets(val src: Int, val dst: Int)
-
- private class Jump(val address: String, val direction: Int)
-
- private class JumpDetector(private val jumpRegex: Regex, private val addressedRegex: Regex) {
- fun detectJump(line: String): Jump? {
- val match = jumpRegex.matchEntire(line) ?: return null
- return Jump(match.getValue("address"), if (match.getValue("direction") == "+") 1 else -1)
- }
-
- fun detectAddressed(line: String) = addressedRegex.matchEntire(line)?.getValue("address")
- }
}
private fun String.countPadding() = indexOfFirst { it != ' ' }
diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexTextArea.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexTextArea.kt
index 677526f3..817fb1ac 100644
--- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexTextArea.kt
+++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/dex/DexTextArea.kt
@@ -18,11 +18,13 @@ package dev.romainguy.kotlin.explorer.dex
import dev.romainguy.kotlin.explorer.CodeTextArea
import dev.romainguy.kotlin.explorer.ExplorerState
+import dev.romainguy.kotlin.explorer.jump.RegexJumpDetector
+// DEX Syntax: ' 0005: if-nez v0, 0008 // +0003'
private val DexJumpRegex =
Regex("^.{9}[0-9a-fA-F]{4}: .+(?
[0-9a-fA-F]{4}) // (?[+-])[0-9a-fA-F]{4}$")
private val DexAddressedRegex = Regex("^.{9}(?[0-9a-fA-F]{4}): .+$")
private val DexLineNumberRegex = Regex("^(? +\\d+: )([0-9a-f]{4}: )", RegexOption.MULTILINE)
class DexTextArea(explorerState: ExplorerState) :
- CodeTextArea(explorerState, DexJumpRegex, DexAddressedRegex, DexLineNumberRegex)
+ CodeTextArea(explorerState, RegexJumpDetector(DexJumpRegex, DexAddressedRegex), DexLineNumberRegex)
diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/CompoundJumpDetector.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/CompoundJumpDetector.kt
new file mode 100644
index 00000000..ec1d9658
--- /dev/null
+++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/CompoundJumpDetector.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 Romain Guy
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dev.romainguy.kotlin.explorer.jump
+
+class CompoundJumpDetector(private vararg val detectors: JumpDetector) : JumpDetector {
+ override fun detectJump(line: String) = detectors.firstNotNullOfOrNull { it.detectJump(line) }
+
+ override fun detectAddressed(line: String) = detectors.firstNotNullOfOrNull { it.detectAddressed(line) }
+}
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/Jump.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/Jump.kt
new file mode 100644
index 00000000..dd44e020
--- /dev/null
+++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/Jump.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2023 Romain Guy
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dev.romainguy.kotlin.explorer.jump
+
+class Jump(val address: Int, val direction: Int)
diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/JumpDetector.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/JumpDetector.kt
new file mode 100644
index 00000000..416ac0e7
--- /dev/null
+++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/JumpDetector.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 Romain Guy
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dev.romainguy.kotlin.explorer.jump
+
+interface JumpDetector {
+ fun detectJump(line: String): Jump?
+
+ fun detectAddressed(line: String): Int?
+}
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/RegexJumpDetector.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/RegexJumpDetector.kt
new file mode 100644
index 00000000..549925ee
--- /dev/null
+++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/jump/RegexJumpDetector.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 Romain Guy
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dev.romainguy.kotlin.explorer.jump
+
+import dev.romainguy.kotlin.explorer.getValue
+
+class RegexJumpDetector(private val jumpRegex: Regex, private val addressedRegex: Regex) : JumpDetector {
+ override fun detectJump(line: String): Jump? {
+ val match = jumpRegex.matchEntire(line) ?: return null
+ return Jump(match.getValue("address").toInt(16), if (match.getValue("direction") == "+") 1 else -1)
+ }
+
+ override fun detectAddressed(line: String) = addressedRegex.matchEntire(line)?.getValue("address")?.toInt(16)
+}
\ No newline at end of file
diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatTextArea.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatTextArea.kt
index 796cc838..454f1509 100644
--- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatTextArea.kt
+++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/oat/OatTextArea.kt
@@ -18,10 +18,29 @@ package dev.romainguy.kotlin.explorer.oat
import dev.romainguy.kotlin.explorer.CodeTextArea
import dev.romainguy.kotlin.explorer.ExplorerState
+import dev.romainguy.kotlin.explorer.jump.CompoundJumpDetector
+import dev.romainguy.kotlin.explorer.jump.RegexJumpDetector
-private val OatJumpRegex =
- Regex("^ +0x[0-9a-fA-F]{8}: .+ (?[+-])\\d+ \\((?0x[0-9a-fA-F]{8})\\)$")
-private val OatAddressedRegex = Regex("^ +(?0x[0-9a-fA-F]{8}): .+$")
+// Arm64 syntax: ' 0x00001040: b.ge #+0x48 (addr 0x1088)'
+private val Arm64JumpRegex =
+ Regex("^ +0x[0-9a-fA-F]{8}: .+ #(?[+-])0x[0-9a-fA-F]+ \\(addr 0x(?[0-9a-fA-F]+)\\)$")
+
+// X86 syntax: ' 0x00001048: jnl/ge +103 (0x000010b5)'
+private val X86JumpRegex =
+ Regex("^ +0x[0-9a-fA-F]{8}: .+ (?[+-])\\d+ \\(0x(?[0-9a-fA-F]{8})\\)$")
+
+private val OatAddressedRegex = Regex("^ +0x(?[0-9a-fA-F]{8}): .+$")
class OatTextArea(explorerState: ExplorerState) :
- CodeTextArea(explorerState, OatJumpRegex, OatAddressedRegex, lineNumberRegex = null)
\ No newline at end of file
+ CodeTextArea(
+ explorerState,
+ CompoundJumpDetector(
+ RegexJumpDetector(Arm64JumpRegex, OatAddressedRegex),
+ RegexJumpDetector(X86JumpRegex, OatAddressedRegex)
+ ),
+ lineNumberRegex = null
+ )
+
+fun main() {
+ println(X86JumpRegex.matchEntire(" 0x00001048: jnl/ge +103 (0x000010b5)"))
+}
\ No newline at end of file