Skip to content

Commit

Permalink
Improve disassembly UI
Browse files Browse the repository at this point in the history
- Unify disassembly dumps
- Show instructions count
- Tweak syntax highlighting
  • Loading branch information
romainguy committed May 16, 2024
1 parent aaedaa0 commit d2bd45b
Show file tree
Hide file tree
Showing 7 changed files with 542 additions and 471 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class CodeBuilder(private val codeStyle: CodeStyle) {
fun startMethod(method: Method) {
sb.append(" ".repeat(codeStyle.indent))
writeLine(method.header)
sb.append(" ".repeat(codeStyle.indent))
writeLine("-- ${method.instructions.size} instructions")
}

fun endMethod() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ private const val Instructions = "insns size"
private const val Positions = "positions"

internal class DexDumpParser {

fun parse(text: String): CodeContent {
return try {
val lines = text.lineSequence().iterator()
Expand Down Expand Up @@ -73,9 +72,14 @@ internal class DexDumpParser {
private fun Iterator<String>.readMethod(className: String): Method {
val (name, type) = next().substringAfterLast(".").split(':', limit = 2)
val instructions = readInstructions()

consumeUntil(Positions)

val positions = readPositions()
return Method("$name$type // $className.$name()", instructions.withLineNumbers(positions))
val returnType = returnTypeFromType(type)
val paramTypes = paramTypesFromType(type).joinToString(", ")

return Method("$returnType $className.$name($paramTypes)", instructions.withLineNumbers(positions))
}

private fun Iterator<String>.readInstructions(): List<Instruction> {
Expand Down Expand Up @@ -117,3 +121,53 @@ private fun String.getValue(name: String): String {
}
return substringAfter('\'').substringBefore('\'')
}

private fun paramTypesFromType(type: String): List<String> {
val types = mutableListOf<String>()
val paramTypes = type.substringAfter('(').substringBeforeLast(')')

var i = 0
while (i < paramTypes.length) {
when (paramTypes[i]) {
'[' -> {
val result = jniTypeToJavaType(paramTypes, i + 1)
types += result.first + "[]"
i = result.second
}
else -> {
val result = jniTypeToJavaType(paramTypes, i)
types += result.first
i = result.second
}
}
}

return types
}

private fun jniTypeToJavaType(
type: String,
index: Int
): Pair<String, Int> {
var endIndex = index
return when (type[index]) {
'B' -> "byte"
'C' -> "char"
'D' -> "double"
'I' -> "int"
'J' -> "long"
'L' -> {
endIndex = type.indexOf(';', index)
type.substring(index + 1, endIndex)
.replace('/', '.')
.replace("java.lang.", "")
}

'S' -> "short"
'V' -> "void"
'Z' -> "boolean"
else -> "<unknown>"
} to endIndex + 1
}

private fun returnTypeFromType(type: String): String = jniTypeToJavaType(type, type.lastIndexOf(')') + 1).first
4 changes: 2 additions & 2 deletions src/jvmMain/resources/themes/kotlin_explorer_disassembly.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@
<style token="MARKUP_COMMENT" fg="808080" italic="true"/>
<style token="MARKUP_DTD" fg="808080"/>
<style token="MARKUP_PROCESSING_INSTRUCTION" fg="808080"/>
<style token="MARKUP_CDATA" fg="cc6600"/>
<style token="MARKUP_CDATA" fg="8c8c8c" fontSize="10" />
<style token="MARKUP_CDATA_DELIMITER" fg="008080"/>
<style token="MARKUP_ENTITY_REFERENCE" fg="008000"/>
<style token="OPERATOR" fg="000000" />
<style token="PREPROCESSOR" fg="089887" />
<style token="PREPROCESSOR" fg="089887" fontSize="10" />
<style token="REGEX" fg="871094" />
<style token="SEPARATOR" fg="000000" />
<style token="VARIABLE" fg="871094" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,41 +97,34 @@ UnclosedCharLiteral = ([\'][^\']*)
CharLiteral = ({UnclosedCharLiteral}[\'])

CommentBegin = ("//")
MetadataBegin = ("--")

LineTerminator = (\n)
WhiteSpace = ([ \t\f])

Label = ({Digit}({Letter}|{Digit})*[\:])

%state CODE
%state CLASS
%state FUNCTION_SIGNATURE

%%

<YYINITIAL> {
"class" { addToken(Token.RESERVED_WORD); }
}
"class" { addToken(Token.RESERVED_WORD); yybegin(CLASS); }

<YYINITIAL> {
{LineTerminator} { addNullToken(); return firstToken; }

{WhiteSpace}+ { addToken(Token.WHITESPACE); }

{Label} { addToken(Token.PREPROCESSOR); yybegin(CODE); }

^{WhiteSpace}+({Letter}|[<])({Letter}|{Digit}|[-\>$])* {
String text = yytext();
int index = text.indexOf('-');
if (index == -1) {
addToken(Token.FUNCTION);
} else {
int start = zzStartRead;
addToken(start, start + index - 1, Token.FUNCTION);
addToken(start + index, zzMarkedPos-1, Token.COMMENT_MULTILINE);
}
yybegin(FUNCTION_SIGNATURE);
^{WhiteSpace}+{Letter}({Letter}|{Digit}|[.])* {
addToken(Token.DATA_TYPE);
yybegin(FUNCTION_SIGNATURE);
}

{MetadataBegin}.* { addToken(Token.MARKUP_CDATA); addNullToken(); return firstToken; }
{CommentBegin}.* { addToken(Token.COMMENT_EOL); addNullToken(); return firstToken; }

<<EOF>> { addNullToken(); return firstToken; }
Expand All @@ -140,13 +133,36 @@ Label = ({Digit}({Letter}|{Digit})*[\:])
. { addToken(Token.IDENTIFIER); }
}

<CLASS> {
{LineTerminator} { addNullToken(); return firstToken; }

{WhiteSpace}+ { addToken(Token.WHITESPACE); }

{CommentBegin}.* { addToken(Token.COMMENT_EOL); addNullToken(); return firstToken; }

<<EOF>> { addNullToken(); return firstToken; }

{Identifier} { addToken(Token.FUNCTION); }
. { addToken(Token.IDENTIFIER); }
}

<FUNCTION_SIGNATURE> {
{LineTerminator} { addNullToken(); return firstToken; }

{WhiteSpace}+ { addToken(Token.WHITESPACE); }

{CommentBegin}.* { addToken(Token.COMMENT_EOL); addNullToken(); return firstToken; }

{Letter}({Letter}|{Digit}|[$.\<\>])+ {
addToken(Token.FUNCTION);
}

(-({Letter}|{Digit}|[$.])+) {
addToken(Token.COMMENT_MULTILINE);
}

([\(].+[\)]) { addToken(Token.IDENTIFIER); }

<<EOF>> { addNullToken(); return firstToken; }

{Identifier} { addToken(Token.IDENTIFIER); }
Expand Down
Loading

0 comments on commit d2bd45b

Please sign in to comment.