Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

auto import from //depot/cupcake/@135843

  • Loading branch information...
commit f6c387128427e121477c1b32ad35cdcaa5101ba3 1 parent f72d5de
The Android Open Source Project authored
Showing with 33,351 additions and 0 deletions.
  1. +66 −0 Android.mk
  2. 0  MODULE_LICENSE_APACHE2
  3. +190 −0 NOTICE
  4. +52 −0 README.txt
  5. +33 −0 dalvikvm/Android.mk
  6. +302 −0 dalvikvm/Main.c
  7. +69 −0 dexdump/Android.mk
  8. +1,171 −0 dexdump/DexDump.c
  9. +330 −0 dexdump/OpCodeNames.c
  10. +26 −0 dexdump/OpCodeNames.h
  11. +52 −0 dexlist/Android.mk
  12. +257 −0 dexlist/DexList.c
  13. +38 −0 dexopt/Android.mk
  14. +488 −0 dexopt/OptMain.c
  15. +165 −0 docs/dalvik-bytecode.css
  16. +1,500 −0 docs/dalvik-bytecode.html
  17. +59 −0 docs/dalvik-constraints.css
  18. +897 −0 docs/dalvik-constraints.html
  19. +211 −0 docs/debugger.html
  20. +736 −0 docs/debugmon.html
  21. +387 −0 docs/dex-format.css
  22. +3,043 −0 docs/dex-format.html
  23. +326 −0 docs/dexopt.html
  24. +240 −0 docs/embedded-vm-control.html
  25. +129 −0 docs/instruction-formats.css
  26. +430 −0 docs/instruction-formats.html
  27. +54 −0 docs/java-bytecode.css
  28. +228 −0 docs/java-bytecode.html
  29. +59 −0 docs/java-constraints.css
  30. +1,080 −0 docs/java-constraints.html
  31. +512 −0 docs/jni-tips.html
  32. +165 −0 docs/libraries.html
  33. +59 −0 docs/opcodes/opcode-00-nop.html
  34. +92 −0 docs/opcodes/opcode-01-move.html
  35. +106 −0 docs/opcodes/opcode-04-move-wide.html
  36. +90 −0 docs/opcodes/opcode-07-move-object.html
  37. +96 −0 docs/opcodes/opcode-0a-move-result.html
  38. +101 −0 docs/opcodes/opcode-0b-move-result-wide.html
  39. +97 −0 docs/opcodes/opcode-0c-move-result-object.html
  40. +79 −0 docs/opcodes/opcode-0d-move-exception.html
  41. +84 −0 docs/opcodes/opcode-0e-return-void.html
  42. +100 −0 docs/opcodes/opcode-0f-return.html
  43. +99 −0 docs/opcodes/opcode-10-return-wide.html
  44. +96 −0 docs/opcodes/opcode-11-return-object.html
  45. +102 −0 docs/opcodes/opcode-12-const.html
  46. +110 −0 docs/opcodes/opcode-16-const-wide.html
  47. +85 −0 docs/opcodes/opcode-1a-const-string.html
  48. +92 −0 docs/opcodes/opcode-1b-const-class.html
  49. +93 −0 docs/opcodes/opcode-1d-monitor-enter.html
  50. +101 −0 docs/opcodes/opcode-1e-monitor-exit.html
  51. +95 −0 docs/opcodes/opcode-1f-check-cast.html
  52. +100 −0 docs/opcodes/opcode-20-instance-of.html
  53. +78 −0 docs/opcodes/opcode-21-array-length.html
  54. +95 −0 docs/opcodes/opcode-22-new-instance.html
  55. +108 −0 docs/opcodes/opcode-23-new-array.html
  56. +144 −0 docs/opcodes/opcode-24-filled-new-array.html
  57. +125 −0 docs/opcodes/opcode-25-filled-new-array-range.html
  58. +96 −0 docs/opcodes/opcode-26-fill-array-data.html
  59. +80 −0 docs/opcodes/opcode-27-throw.html
  60. +73 −0 docs/opcodes/opcode-28-goto.html
  61. +73 −0 docs/opcodes/opcode-29-goto-16.html
  62. +66 −0 docs/opcodes/opcode-2a-goto-32.html
  63. +103 −0 docs/opcodes/opcode-2b-packed-switch.html
  64. +110 −0 docs/opcodes/opcode-2c-sparse-switch.html
  65. +121 −0 docs/opcodes/opcode-2d-cmp-kind.html
  66. +101 −0 docs/opcodes/opcode-32-if-test.html
  67. +100 −0 docs/opcodes/opcode-38-if-testz.html
  68. +113 −0 docs/opcodes/opcode-44-aget.html
  69. +98 −0 docs/opcodes/opcode-4b-aput.html
  70. +109 −0 docs/opcodes/opcode-52-iget.html
  71. +112 −0 docs/opcodes/opcode-59-iput.html
  72. +106 −0 docs/opcodes/opcode-60-sget.html
  73. +108 −0 docs/opcodes/opcode-67-sput.html
  74. +108 −0 docs/opcodes/opcode-7b-unop.html
  75. +120 −0 docs/opcodes/opcode-90-binop.html
  76. +120 −0 docs/opcodes/opcode-b0-binop-2addr.html
  77. +94 −0 docs/opcodes/opcode-d0-binop-lit16.html
  78. +97 −0 docs/opcodes/opcode-d8-binop-lit8.html
  79. +166 −0 docs/opcodes/opcode.css
  80. +27 −0 docs/prettify.css
  81. +1,280 −0 docs/prettify.js
  82. +159 −0 docs/verifier.html
  83. +18 −0 dvz/Android.mk
  84. +109 −0 dvz/dvz.c
  85. +7 −0 dx/.classpath
  86. +17 −0 dx/.project
  87. +65 −0 dx/Android.mk
  88. +2 −0  dx/README.txt
  89. +278 −0 dx/etc/bytecode.txt
  90. +77 −0 dx/etc/dx
  91. +51 −0 dx/etc/dx.bat
  92. +39 −0 dx/etc/jasmin
  93. BIN  dx/etc/jasmin.jar
  94. +1 −0  dx/etc/manifest.txt
  95. +141 −0 dx/etc/opcode-gen
  96. +22 −0 dx/etc/run-opcode-gen
  97. +31 −0 dx/src/Android.mk
  98. +25 −0 dx/src/com/android/dx/Version.java
  99. +67 −0 dx/src/com/android/dx/cf/attrib/AttAnnotationDefault.java
  100. +145 −0 dx/src/com/android/dx/cf/attrib/AttCode.java
  101. +77 −0 dx/src/com/android/dx/cf/attrib/AttConstantValue.java
  102. +37 −0 dx/src/com/android/dx/cf/attrib/AttDeprecated.java
  103. +78 −0 dx/src/com/android/dx/cf/attrib/AttEnclosingMethod.java
  104. +68 −0 dx/src/com/android/dx/cf/attrib/AttExceptions.java
  105. +64 −0 dx/src/com/android/dx/cf/attrib/AttInnerClasses.java
  106. +65 −0 dx/src/com/android/dx/cf/attrib/AttLineNumberTable.java
  107. +36 −0 dx/src/com/android/dx/cf/attrib/AttLocalVariableTable.java
  108. +36 −0 dx/src/com/android/dx/cf/attrib/AttLocalVariableTypeTable.java
  109. +40 −0 dx/src/com/android/dx/cf/attrib/AttRuntimeInvisibleAnnotations.java
  110. +42 −0 dx/src/com/android/dx/cf/attrib/AttRuntimeInvisibleParameterAnnotations.java
  111. +40 −0 dx/src/com/android/dx/cf/attrib/AttRuntimeVisibleAnnotations.java
  112. +42 −0 dx/src/com/android/dx/cf/attrib/AttRuntimeVisibleParameterAnnotations.java
  113. +59 −0 dx/src/com/android/dx/cf/attrib/AttSignature.java
  114. +59 −0 dx/src/com/android/dx/cf/attrib/AttSourceFile.java
  115. +37 −0 dx/src/com/android/dx/cf/attrib/AttSynthetic.java
  116. +72 −0 dx/src/com/android/dx/cf/attrib/BaseAnnotations.java
  117. +46 −0 dx/src/com/android/dx/cf/attrib/BaseAttribute.java
  118. +65 −0 dx/src/com/android/dx/cf/attrib/BaseLocalVariables.java
  119. +73 −0 dx/src/com/android/dx/cf/attrib/BaseParameterAnnotations.java
  120. +137 −0 dx/src/com/android/dx/cf/attrib/InnerClassList.java
  121. +91 −0 dx/src/com/android/dx/cf/attrib/RawAttribute.java
  122. +11 −0 dx/src/com/android/dx/cf/attrib/package.html
  123. +545 −0 dx/src/com/android/dx/cf/code/BaseMachine.java
  124. +449 −0 dx/src/com/android/dx/cf/code/BasicBlocker.java
  125. +145 −0 dx/src/com/android/dx/cf/code/ByteBlock.java
  126. +75 −0 dx/src/com/android/dx/cf/code/ByteBlockList.java
  127. +317 −0 dx/src/com/android/dx/cf/code/ByteCatchList.java
  128. +649 −0 dx/src/com/android/dx/cf/code/ByteOps.java
  129. +1,393 −0 dx/src/com/android/dx/cf/code/BytecodeArray.java
  130. +254 −0 dx/src/com/android/dx/cf/code/ConcreteMethod.java
  131. +305 −0 dx/src/com/android/dx/cf/code/ExecutionStack.java
  132. +415 −0 dx/src/com/android/dx/cf/code/Frame.java
  133. +184 −0 dx/src/com/android/dx/cf/code/LineNumberList.java
  134. +374 −0 dx/src/com/android/dx/cf/code/LocalVariableList.java
  135. +181 −0 dx/src/com/android/dx/cf/code/LocalsArray.java
  136. +462 −0 dx/src/com/android/dx/cf/code/LocalsArraySet.java
  137. +208 −0 dx/src/com/android/dx/cf/code/Machine.java
  138. +305 −0 dx/src/com/android/dx/cf/code/Merger.java
  139. +246 −0 dx/src/com/android/dx/cf/code/OneLocalsArray.java
  140. +108 −0 dx/src/com/android/dx/cf/code/ReturnAddress.java
  141. +1,667 −0 dx/src/com/android/dx/cf/code/Ropper.java
  142. +936 −0 dx/src/com/android/dx/cf/code/RopperMachine.java
  143. +37 −0 dx/src/com/android/dx/cf/code/SimException.java
  144. +701 −0 dx/src/com/android/dx/cf/code/Simulator.java
  145. +193 −0 dx/src/com/android/dx/cf/code/SwitchList.java
  146. +198 −0 dx/src/com/android/dx/cf/code/ValueAwareMachine.java
  147. +10 −0 dx/src/com/android/dx/cf/code/package.html
  148. +335 −0 dx/src/com/android/dx/cf/cst/ConstantPoolParser.java
  149. +55 −0 dx/src/com/android/dx/cf/cst/ConstantTags.java
  150. +474 −0 dx/src/com/android/dx/cf/direct/AnnotationParser.java
  151. +134 −0 dx/src/com/android/dx/cf/direct/AttributeFactory.java
  152. +164 −0 dx/src/com/android/dx/cf/direct/AttributeListParser.java
Sorry, we could not display the entire diff because too many files (7,698) changed.
View
66 Android.mk
@@ -0,0 +1,66 @@
+# Copyright (C) 2006 The Android Open Source Project
+#
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
+ libdex \
+ vm \
+ dalvikvm \
+ dexlist \
+ dexopt \
+ dexdump \
+ dvz \
+ dx \
+ libcore \
+ libnativehelper \
+ tools \
+ ))
+
+include $(subdirs)
+
+
+.PHONY: dex dex-debug
+ifeq ($(DONT_INSTALL_DEX_FILES),true)
+dex:
+ @echo "Forcing a remake with DONT_INSTALL_DEX_FILES=false"
+ $(hide) $(MAKE) DONT_INSTALL_DEX_FILES=false
+else
+# DONT_INSTALL_DEX_FILES is already false, so a normal make takes care of it.
+dex: $(DEFAULT_GOAL)
+endif
+
+d :=
+ifneq ($(GENERATE_DEX_DEBUG),)
+d := debug
+endif
+ifneq ($(DONT_INSTALL_DEX_FILES),true)
+d := $(d)-install
+endif
+ifneq ($(d),debug-install)
+# generate the debug .dex files, with a copy in ./dalvik/DEBUG-FILES.
+# We need to rebuild the .dex files for the debug output to be generated.
+# The "touch -c $(DX)" is a hack that we know will force
+# a rebuild of the .dex files. If $(DX) doesn't exist yet,
+# we won't touch it (-c) and the normal build will create
+# the .dex files naturally.
+dex-debug:
+ @echo "Forcing an app rebuild with GENERATE_DEX_DEBUG=true"
+ @touch -c $(DX)
+ $(hide) $(MAKE) DONT_INSTALL_DEX_FILES=false GENERATE_DEX_DEBUG=true
+else
+# GENERATE_DEX_DEBUG and DONT_INSTALL_DEX_FILES are already set properly,
+# so a normal make takes care of it.
+dex-debug: $(DEFAULT_GOAL)
+endif
View
0  MODULE_LICENSE_APACHE2
No changes.
View
190 NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
View
52 README.txt
@@ -0,0 +1,52 @@
+This directory contains the Dalvik virtual machine and associated
+class library.
+
+A note about the licenses and header comments
+---------------------------------------------
+
+Much of the code under this directory originally came from the Apache
+Harmony project, and as such contains the standard Apache header
+comment. Some of the code was written originally for the Android
+project, and as such contains the standard Android header comment.
+Some files contain code from both projects. In these cases, the header
+comment is a combination of the other two, and the portions of the
+code from Harmony are identified as indicated in the comment.
+
+Here is the combined header comment:
+
+/*
+ * Copyright (C) <year> The Android Open Source Project
+ *
+ * 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.
+ *
+ * ----------
+ *
+ * Portions of the code surrounded by "// BEGIN Harmony code" and
+ * "// END Harmony code" are copyrighted and licensed separately, as
+ * follows:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
View
33 dalvikvm/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# 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.
+
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ Main.c
+
+LOCAL_C_INCLUDES := \
+ $(JNI_H_INCLUDE) \
+ dalvik/include
+
+LOCAL_SHARED_LIBRARIES := \
+ libdvm \
+ libssl \
+ libz
+
+LOCAL_MODULE:= dalvikvm
+
+include $(BUILD_EXECUTABLE)
View
302 dalvikvm/Main.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.
+ */
+/*
+ * Command-line invocation of the Dalvik VM.
+ */
+#include "jni.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <assert.h>
+
+
+/*
+ * We want failed write() calls to just return with an error.
+ */
+static void blockSigpipe()
+{
+ sigset_t mask;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGPIPE);
+ if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)
+ fprintf(stderr, "WARNING: SIGPIPE not blocked\n");
+}
+
+/*
+ * Create a String[] and populate it with the contents of argv.
+ */
+static jobjectArray createStringArray(JNIEnv* env, char* const argv[], int argc)
+{
+ jclass stringClass = NULL;
+ jobjectArray strArray = NULL;
+ jobjectArray result = NULL;
+ int i;
+
+ stringClass = (*env)->FindClass(env, "java/lang/String");
+ if ((*env)->ExceptionCheck(env)) {
+ fprintf(stderr, "Got exception while finding class String\n");
+ goto bail;
+ }
+ assert(stringClass != NULL);
+ strArray = (*env)->NewObjectArray(env, argc, stringClass, NULL);
+ if ((*env)->ExceptionCheck(env)) {
+ fprintf(stderr, "Got exception while creating String array\n");
+ goto bail;
+ }
+ assert(strArray != NULL);
+
+ for (i = 0; i < argc; i++) {
+ jstring argStr;
+
+ argStr = (*env)->NewStringUTF(env, argv[i]);
+ if ((*env)->ExceptionCheck(env)) {
+ fprintf(stderr, "Got exception while allocating Strings\n");
+ goto bail;
+ }
+ assert(argStr != NULL);
+ (*env)->SetObjectArrayElement(env, strArray, i, argStr);
+ (*env)->DeleteLocalRef(env, argStr);
+ }
+
+ /* return the array, and ensure we don't delete the local ref to it */
+ result = strArray;
+ strArray = NULL;
+
+bail:
+ (*env)->DeleteLocalRef(env, stringClass);
+ (*env)->DeleteLocalRef(env, strArray);
+ return result;
+}
+
+/*
+ * Determine whether or not the specified method is public.
+ *
+ * Returns JNI_TRUE on success, JNI_FALSE on failure.
+ */
+static int methodIsPublic(JNIEnv* env, jclass clazz, jmethodID methodId)
+{
+ static const int PUBLIC = 0x0001; // java.lang.reflect.Modifiers.PUBLIC
+ jobject refMethod = NULL;
+ jclass methodClass = NULL;
+ jmethodID getModifiersId;
+ int modifiers;
+ int result = JNI_FALSE;
+
+ refMethod = (*env)->ToReflectedMethod(env, clazz, methodId, JNI_FALSE);
+ if (refMethod == NULL) {
+ fprintf(stderr, "Dalvik VM unable to get reflected method\n");
+ goto bail;
+ }
+
+ /*
+ * We now have a Method instance. We need to call
+ * its getModifiers() method.
+ */
+ methodClass = (*env)->FindClass(env, "java/lang/reflect/Method");
+ if (methodClass == NULL) {
+ fprintf(stderr, "Dalvik VM unable to find class Method\n");
+ goto bail;
+ }
+ getModifiersId = (*env)->GetMethodID(env, methodClass,
+ "getModifiers", "()I");
+ if (methodClass == NULL) {
+ fprintf(stderr, "Dalvik VM unable to find reflect.Method.getModifiers\n");
+ goto bail;
+ }
+
+ modifiers = (*env)->CallIntMethod(env, refMethod, getModifiersId);
+ if ((modifiers & PUBLIC) == 0) {
+ fprintf(stderr, "Dalvik VM: main() is not public\n");
+ goto bail;
+ }
+
+ result = JNI_TRUE;
+
+bail:
+ (*env)->DeleteLocalRef(env, refMethod);
+ (*env)->DeleteLocalRef(env, methodClass);
+ return result;
+}
+
+/*
+ * Parse arguments. Most of it just gets passed through to the VM. The
+ * JNI spec defines a handful of standard arguments.
+ */
+int main(int argc, char* const argv[])
+{
+ JavaVM* vm = NULL;
+ JNIEnv* env = NULL;
+ JavaVMInitArgs initArgs;
+ JavaVMOption* options = NULL;
+ char* slashClass = NULL;
+ int optionCount, curOpt, i, argIdx;
+ int needExtra = JNI_FALSE;
+ int result = 1;
+
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* ignore argv[0] */
+ argv++;
+ argc--;
+
+ /*
+ * If we're adding any additional stuff, e.g. function hook specifiers,
+ * add them to the count here.
+ *
+ * We're over-allocating, because this includes the options to the VM
+ * plus the options to the program.
+ */
+ optionCount = argc;
+
+ options = (JavaVMOption*) malloc(sizeof(JavaVMOption) * optionCount);
+ memset(options, 0, sizeof(JavaVMOption) * optionCount);
+
+ /*
+ * Copy options over. Everything up to the name of the class starts
+ * with a '-' (the function hook stuff is strictly internal).
+ *
+ * [Do we need to catch & handle "-jar" here?]
+ */
+ for (curOpt = argIdx = 0; argIdx < argc; argIdx++) {
+ if (argv[argIdx][0] != '-' && !needExtra)
+ break;
+ options[curOpt++].optionString = strdup(argv[argIdx]);
+
+ /* some options require an additional arg */
+ needExtra = JNI_FALSE;
+ if (strcmp(argv[argIdx], "-classpath") == 0 ||
+ strcmp(argv[argIdx], "-cp") == 0)
+ /* others? */
+ {
+ needExtra = JNI_TRUE;
+ }
+ }
+
+ if (needExtra) {
+ fprintf(stderr, "Dalvik VM requires value after last option flag\n");
+ goto bail;
+ }
+
+ /* insert additional internal options here */
+
+ assert(curOpt <= optionCount);
+
+ initArgs.version = JNI_VERSION_1_4;
+ initArgs.options = options;
+ initArgs.nOptions = curOpt;
+ initArgs.ignoreUnrecognized = JNI_FALSE;
+
+ //printf("nOptions = %d\n", initArgs.nOptions);
+
+ blockSigpipe();
+
+ /*
+ * Start VM. The current thread becomes the main thread of the VM.
+ */
+ if (JNI_CreateJavaVM(&vm, &env, &initArgs) < 0) {
+ fprintf(stderr, "Dalvik VM init failed (check log file)\n");
+ goto bail;
+ }
+
+ /*
+ * Make sure they provided a class name. We do this after VM init
+ * so that things like "-Xrunjdwp:help" have the opportunity to emit
+ * a usage statement.
+ */
+ if (argIdx == argc) {
+ fprintf(stderr, "Dalvik VM requires a class name\n");
+ goto bail;
+ }
+
+ /*
+ * We want to call main() with a String array with our arguments in it.
+ * Create an array and populate it. Note argv[0] is not included.
+ */
+ jobjectArray strArray;
+ strArray = createStringArray(env, &argv[argIdx+1], argc-argIdx-1);
+ if (strArray == NULL)
+ goto bail;
+
+ /*
+ * Find [class].main(String[]).
+ */
+ jclass startClass;
+ jmethodID startMeth;
+ char* cp;
+
+ /* convert "com.android.Blah" to "com/android/Blah" */
+ slashClass = strdup(argv[argIdx]);
+ for (cp = slashClass; *cp != '\0'; cp++)
+ if (*cp == '.')
+ *cp = '/';
+
+ startClass = (*env)->FindClass(env, slashClass);
+ if (startClass == NULL) {
+ fprintf(stderr, "Dalvik VM unable to locate class '%s'\n", slashClass);
+ goto bail;
+ }
+
+ startMeth = (*env)->GetStaticMethodID(env, startClass,
+ "main", "([Ljava/lang/String;)V");
+ if (startMeth == NULL) {
+ fprintf(stderr, "Dalvik VM unable to find static main(String[]) in '%s'\n",
+ slashClass);
+ goto bail;
+ }
+
+ /*
+ * Make sure the method is public. JNI doesn't prevent us from calling
+ * a private method, so we have to check it explicitly.
+ */
+ if (!methodIsPublic(env, startClass, startMeth))
+ goto bail;
+
+ /*
+ * Invoke main().
+ */
+ (*env)->CallStaticVoidMethod(env, startClass, startMeth, strArray);
+
+ if (!(*env)->ExceptionCheck(env))
+ result = 0;
+
+bail:
+ /*printf("Shutting down Dalvik VM\n");*/
+ if (vm != NULL) {
+ /*
+ * This allows join() and isAlive() on the main thread to work
+ * correctly, and also provides uncaught exception handling.
+ */
+ if ((*vm)->DetachCurrentThread(vm) != JNI_OK) {
+ fprintf(stderr, "Warning: unable to detach main thread\n");
+ result = 1;
+ }
+
+ if ((*vm)->DestroyJavaVM(vm) != 0)
+ fprintf(stderr, "Warning: Dalvik VM did not shut down cleanly\n");
+ /*printf("\nDalvik VM has exited\n");*/
+ }
+
+ for (i = 0; i < optionCount; i++)
+ free((char*) options[i].optionString);
+ free(options);
+ free(slashClass);
+ /*printf("--- VM is down, process exiting\n");*/
+ return result;
+}
+
View
69 dexdump/Android.mk
@@ -0,0 +1,69 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# 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.
+
+#
+# dexdump, similar in purpose to objdump.
+#
+LOCAL_PATH:= $(call my-dir)
+
+dexdump_src_files := \
+ DexDump.c \
+ OpCodeNames.c
+
+dexdump_c_includes := \
+ dalvik \
+ $(JNI_H_INCLUDE)
+
+dexdump_shared_libraries :=
+
+dexdump_static_libraries := \
+ libdex
+
+##
+##
+## Build the device command line tool dexdump
+##
+##
+ifneq ($(SDK_ONLY),true) # SDK_only doesn't need device version
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := dexdump
+LOCAL_SRC_FILES := $(dexdump_src_files)
+LOCAL_C_INCLUDES := $(dexdump_c_includes)
+LOCAL_SHARED_LIBRARIES := $(dexdump_shared_libraries) libz liblog
+LOCAL_STATIC_LIBRARIES := $(dexdump_static_libraries)
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := debug development
+LOCAL_LDLIBS +=
+include $(BUILD_EXECUTABLE)
+
+endif # !SDK_ONLY
+
+
+##
+##
+## Build the host command line tool dexdump
+##
+##
+ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean
+include $(CLEAR_VARS)
+LOCAL_MODULE := dexdump
+LOCAL_SRC_FILES := $(dexdump_src_files)
+LOCAL_C_INCLUDES := $(dexdump_c_includes)
+LOCAL_SHARED_LIBRARIES := $(dexdump_shared_libraries)
+LOCAL_STATIC_LIBRARIES := $(dexdump_static_libraries) liblog
+LOCAL_LDLIBS += -lpthread -lz
+include $(BUILD_HOST_EXECUTABLE)
+endif # !TARGET_SIMULATOR
+
View
1,171 dexdump/DexDump.c
@@ -0,0 +1,1171 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.
+ */
+/*
+ * The "dexdump" tool is intended to mimic "objdump". When possible, use
+ * similar command-line arguments.
+ *
+ * TODO: rework the output format to be more regexp-friendly
+ */
+#include "libdex/DexFile.h"
+#include "libdex/DexCatch.h"
+#include "libdex/DexClass.h"
+#include "libdex/DexProto.h"
+#include "libdex/InstrUtils.h"
+#include "libdex/SysUtil.h"
+#include "libdex/CmdUtils.h"
+
+#include "dexdump/OpCodeNames.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <errno.h>
+#include <assert.h>
+
+static const char* gProgName = "dexdump";
+
+static InstructionWidth* gInstrWidth;
+static InstructionFormat* gInstrFormat;
+
+/* command-line options */
+struct {
+ bool disassemble;
+ bool showFileHeaders;
+ bool showSectionHeaders;
+ const char* tempFileName;
+} gOptions;
+
+/* basic info about a field or method */
+typedef struct FieldMethodInfo {
+ const char* classDescriptor;
+ const char* name;
+ const char* signature;
+} FieldMethodInfo;
+
+/*
+ * Get 2 little-endian bytes.
+ */
+static inline u2 get2LE(unsigned char const* pSrc)
+{
+ return pSrc[0] | (pSrc[1] << 8);
+}
+
+/*
+ * Return a newly-allocated string for the "dot version" of the class
+ * name for the given type descriptor. That is, The initial "L" and
+ * final ";" (if any) have been removed and all occurrences of '/'
+ * have been changed to '.'.
+ */
+static char* descriptorToDot(const char* str)
+{
+ size_t at = strlen(str);
+ char* newStr;
+
+ if (str[0] == 'L') {
+ assert(str[at - 1] == ';');
+ at -= 2; /* Two fewer chars to copy. */
+ str++; /* Skip the 'L'. */
+ }
+
+ newStr = malloc(at + 1); /* Add one for the '\0'. */
+ newStr[at] = '\0';
+
+ while (at > 0) {
+ at--;
+ newStr[at] = (str[at] == '/') ? '.' : str[at];
+ }
+
+ return newStr;
+}
+
+/*
+ * Count the number of '1' bits in a word.
+ *
+ * Having completed this, I'm ready for an interview at Google.
+ *
+ * TODO? there's a parallel version w/o loops. Performance not currently
+ * important.
+ */
+static int countOnes(u4 val)
+{
+ int count = 0;
+
+ while (val != 0) {
+ val &= val-1;
+ count++;
+ }
+
+ return count;
+}
+
+
+/*
+ * Flag for use with createAccessFlagStr().
+ */
+typedef enum AccessFor {
+ kAccessForClass = 0, kAccessForMethod = 1, kAccessForField = 2,
+ kAccessForMAX
+} AccessFor;
+
+/*
+ * Create a new string with human-readable access flags.
+ *
+ * In the base language the access_flags fields are type u2; in Dalvik
+ * they're u4.
+ */
+static char* createAccessFlagStr(u4 flags, AccessFor forWhat)
+{
+#define NUM_FLAGS 18
+ static const char* kAccessStrings[kAccessForMAX][NUM_FLAGS] = {
+ {
+ /* class, inner class */
+ "PUBLIC", /* 0x0001 */
+ "PRIVATE", /* 0x0002 */
+ "PROTECTED", /* 0x0004 */
+ "STATIC", /* 0x0008 */
+ "FINAL", /* 0x0010 */
+ "?", /* 0x0020 */
+ "?", /* 0x0040 */
+ "?", /* 0x0080 */
+ "?", /* 0x0100 */
+ "INTERFACE", /* 0x0200 */
+ "ABSTRACT", /* 0x0400 */
+ "?", /* 0x0800 */
+ "SYNTHETIC", /* 0x1000 */
+ "ANNOTATION", /* 0x2000 */
+ "ENUM", /* 0x4000 */
+ "?", /* 0x8000 */
+ "VERIFIED", /* 0x10000 */
+ "OPTIMIZED", /* 0x20000 */
+ },
+ {
+ /* method */
+ "PUBLIC", /* 0x0001 */
+ "PRIVATE", /* 0x0002 */
+ "PROTECTED", /* 0x0004 */
+ "STATIC", /* 0x0008 */
+ "FINAL", /* 0x0010 */
+ "SYNCHRONIZED", /* 0x0020 */
+ "BRIDGE", /* 0x0040 */
+ "VARARGS", /* 0x0080 */
+ "NATIVE", /* 0x0100 */
+ "?", /* 0x0200 */
+ "ABSTRACT", /* 0x0400 */
+ "STRICT", /* 0x0800 */
+ "SYNTHETIC", /* 0x1000 */
+ "?", /* 0x2000 */
+ "?", /* 0x4000 */
+ "MIRANDA", /* 0x8000 */
+ "CONSTRUCTOR", /* 0x10000 */
+ "DECLARED_SYNCHRONIZED", /* 0x20000 */
+ },
+ {
+ /* field */
+ "PUBLIC", /* 0x0001 */
+ "PRIVATE", /* 0x0002 */
+ "PROTECTED", /* 0x0004 */
+ "STATIC", /* 0x0008 */
+ "FINAL", /* 0x0010 */
+ "?", /* 0x0020 */
+ "VOLATILE", /* 0x0040 */
+ "TRANSIENT", /* 0x0080 */
+ "?", /* 0x0100 */
+ "?", /* 0x0200 */
+ "?", /* 0x0400 */
+ "?", /* 0x0800 */
+ "SYNTHETIC", /* 0x1000 */
+ "?", /* 0x2000 */
+ "ENUM", /* 0x4000 */
+ "?", /* 0x8000 */
+ "?", /* 0x10000 */
+ "?", /* 0x20000 */
+ },
+ };
+ const int kLongest = 21; /* strlen of longest string above */
+ int i, count;
+ char* str;
+ char* cp;
+
+ /*
+ * Allocate enough storage to hold the expected number of strings,
+ * plus a space between each. We over-allocate, using the longest
+ * string above as the base metric.
+ */
+ count = countOnes(flags);
+ cp = str = (char*) malloc(count * (kLongest+1) +1);
+
+ for (i = 0; i < NUM_FLAGS; i++) {
+ if (flags & 0x01) {
+ const char* accessStr = kAccessStrings[forWhat][i];
+ int len = strlen(accessStr);
+ if (cp != str)
+ *cp++ = ' ';
+
+ memcpy(cp, accessStr, len);
+ cp += len;
+ }
+ flags >>= 1;
+ }
+ *cp = '\0';
+
+ return str;
+}
+
+
+/*
+ * Dump the file header.
+ */
+void dumpFileHeader(const DexFile* pDexFile)
+{
+ const DexHeader* pHeader = pDexFile->pHeader;
+
+ printf("DEX file header:\n");
+ printf("magic : '%.8s'\n", pHeader->magic);
+ printf("checksum : %08x\n", pHeader->checksum);
+ printf("signature : %02x%02x...%02x%02x\n",
+ pHeader->signature[0], pHeader->signature[1],
+ pHeader->signature[kSHA1DigestLen-2],
+ pHeader->signature[kSHA1DigestLen-1]);
+ printf("file_size : %d\n", pHeader->fileSize);
+ printf("header_size : %d\n", pHeader->headerSize);
+ printf("link_size : %d\n", pHeader->linkSize);
+ printf("link_off : %d (0x%06x)\n",
+ pHeader->linkOff, pHeader->linkOff);
+ printf("string_ids_size : %d\n", pHeader->stringIdsSize);
+ printf("string_ids_off : %d (0x%06x)\n",
+ pHeader->stringIdsOff, pHeader->stringIdsOff);
+ printf("type_ids_size : %d\n", pHeader->typeIdsSize);
+ printf("type_ids_off : %d (0x%06x)\n",
+ pHeader->typeIdsOff, pHeader->typeIdsOff);
+ printf("field_ids_size : %d\n", pHeader->fieldIdsSize);
+ printf("field_ids_off : %d (0x%06x)\n",
+ pHeader->fieldIdsOff, pHeader->fieldIdsOff);
+ printf("method_ids_size : %d\n", pHeader->methodIdsSize);
+ printf("method_ids_off : %d (0x%06x)\n",
+ pHeader->methodIdsOff, pHeader->methodIdsOff);
+ printf("class_defs_size : %d\n", pHeader->classDefsSize);
+ printf("class_defs_off : %d (0x%06x)\n",
+ pHeader->classDefsOff, pHeader->classDefsOff);
+ printf("data_size : %d\n", pHeader->dataSize);
+ printf("data_off : %d (0x%06x)\n",
+ pHeader->dataOff, pHeader->dataOff);
+ printf("\n");
+}
+
+/*
+ * Dump a class_def_item.
+ */
+void dumpClassDef(DexFile* pDexFile, int idx)
+{
+ const DexClassDef* pClassDef;
+ const u1* pEncodedData;
+ DexClassData* pClassData;
+
+ pClassDef = dexGetClassDef(pDexFile, idx);
+ pEncodedData = dexGetClassData(pDexFile, pClassDef);
+ pClassData = dexReadAndVerifyClassData(&pEncodedData, NULL);
+
+ if (pClassData == NULL) {
+ fprintf(stderr, "Trouble reading class data\n");
+ return;
+ }
+
+ printf("Class #%d header:\n", idx);
+ printf("class_idx : %d\n", pClassDef->classIdx);
+ printf("access_flags : %d (0x%04x)\n",
+ pClassDef->accessFlags, pClassDef->accessFlags);
+ printf("superclass_idx : %d\n", pClassDef->superclassIdx);
+ printf("interfaces_off : %d (0x%06x)\n",
+ pClassDef->interfacesOff, pClassDef->interfacesOff);
+ printf("source_file_idx : %d\n", pClassDef->sourceFileIdx);
+ printf("annotations_off : %d (0x%06x)\n",
+ pClassDef->annotationsOff, pClassDef->annotationsOff);
+ printf("class_data_off : %d (0x%06x)\n",
+ pClassDef->classDataOff, pClassDef->classDataOff);
+ printf("static_fields_size : %d\n", pClassData->header.staticFieldsSize);
+ printf("instance_fields_size: %d\n",
+ pClassData->header.instanceFieldsSize);
+ printf("direct_methods_size : %d\n", pClassData->header.directMethodsSize);
+ printf("virtual_methods_size: %d\n",
+ pClassData->header.virtualMethodsSize);
+ printf("\n");
+
+ free(pClassData);
+}
+
+/*
+ * Dump an interface.
+ */
+void dumpInterface(const DexFile* pDexFile, const DexTypeItem* pTypeItem,
+ int i)
+{
+ const char* interfaceName =
+ dexStringByTypeIdx(pDexFile, pTypeItem->typeIdx);
+
+ printf(" #%d : '%s'\n", i, interfaceName);
+}
+
+/*
+ * Dump the catches table associated with the code.
+ */
+void dumpCatches(DexFile* pDexFile, const DexCode* pCode)
+{
+ u4 triesSize = pCode->triesSize;
+
+ if (triesSize == 0) {
+ printf(" catches : (none)\n");
+ return;
+ }
+
+ printf(" catches : %d\n", triesSize);
+
+ const DexTry* pTries = dexGetTries(pCode);
+ u4 i;
+
+ for (i = 0; i < triesSize; i++) {
+ const DexTry* pTry = &pTries[i];
+ u4 start = pTry->startAddr;
+ u4 end = start + pTry->insnCount;
+ DexCatchIterator iterator;
+
+ printf(" 0x%04x - 0x%04x\n", start, end);
+
+ dexCatchIteratorInit(&iterator, pCode, pTry->handlerOff);
+
+ for (;;) {
+ DexCatchHandler* handler = dexCatchIteratorNext(&iterator);
+ const char* descriptor;
+
+ if (handler == NULL) {
+ break;
+ }
+
+ descriptor = (handler->typeIdx == kDexNoIndex) ? "<any>" :
+ dexStringByTypeIdx(pDexFile, handler->typeIdx);
+
+ printf(" %s -> 0x%04x\n", descriptor,
+ handler->address);
+ }
+ }
+}
+
+static int dumpPositionsCb(void *cnxt, u4 address, u4 lineNum)
+{
+ printf(" 0x%04x line=%d\n", address, lineNum);
+ return 0;
+}
+
+/*
+ * Dump the positions list.
+ */
+void dumpPositions(DexFile* pDexFile, const DexCode* pCode,
+ const DexMethod *pDexMethod)
+{
+ printf(" positions : \n");
+ const DexMethodId *pMethodId
+ = dexGetMethodId(pDexFile, pDexMethod->methodIdx);
+ const char *classDescriptor
+ = dexStringByTypeIdx(pDexFile, pMethodId->classIdx);
+
+ dexDecodeDebugInfo(pDexFile, pCode, classDescriptor, pMethodId->protoIdx,
+ pDexMethod->accessFlags, dumpPositionsCb, NULL, NULL);
+}
+
+static void dumpLocalsCb(void *cnxt, u2 reg, u4 startAddress,
+ u4 endAddress, const char *name, const char *descriptor,
+ const char *signature)
+{
+ printf(" 0x%04x - 0x%04x reg=%d %s %s %s\n",
+ startAddress, endAddress, reg, name, descriptor,
+ signature);
+}
+
+/*
+ * Dump the locals list.
+ */
+void dumpLocals(DexFile* pDexFile, const DexCode* pCode,
+ const DexMethod *pDexMethod)
+{
+ printf(" locals : \n");
+
+ const DexMethodId *pMethodId
+ = dexGetMethodId(pDexFile, pDexMethod->methodIdx);
+ const char *classDescriptor
+ = dexStringByTypeIdx(pDexFile, pMethodId->classIdx);
+
+ dexDecodeDebugInfo(pDexFile, pCode, classDescriptor, pMethodId->protoIdx,
+ pDexMethod->accessFlags, NULL, dumpLocalsCb, NULL);
+}
+
+/*
+ * Get information about a method.
+ */
+bool getMethodInfo(DexFile* pDexFile, u4 methodIdx, FieldMethodInfo* pMethInfo)
+{
+ const DexMethodId* pMethodId;
+
+ if (methodIdx >= pDexFile->pHeader->methodIdsSize)
+ return false;
+
+ pMethodId = dexGetMethodId(pDexFile, methodIdx);
+ pMethInfo->name = dexStringById(pDexFile, pMethodId->nameIdx);
+ pMethInfo->signature = dexCopyDescriptorFromMethodId(pDexFile, pMethodId);
+
+ pMethInfo->classDescriptor =
+ dexStringByTypeIdx(pDexFile, pMethodId->classIdx);
+ return true;
+}
+
+/*
+ * Get information about a field.
+ */
+bool getFieldInfo(DexFile* pDexFile, u4 fieldIdx, FieldMethodInfo* pFieldInfo)
+{
+ const DexFieldId* pFieldId;
+
+ if (fieldIdx >= pDexFile->pHeader->fieldIdsSize)
+ return false;
+
+ pFieldId = dexGetFieldId(pDexFile, fieldIdx);
+ pFieldInfo->name = dexStringById(pDexFile, pFieldId->nameIdx);
+ pFieldInfo->signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
+ pFieldInfo->classDescriptor =
+ dexStringByTypeIdx(pDexFile, pFieldId->classIdx);
+ return true;
+}
+
+
+/*
+ * Look up a class' descriptor.
+ */
+const char* getClassDescriptor(DexFile* pDexFile, u4 classIdx)
+{
+ return dexStringByTypeIdx(pDexFile, classIdx);
+}
+
+/*
+ * Dump a single instruction.
+ */
+void dumpInstruction(DexFile* pDexFile, const DexCode* pCode, int insnIdx,
+ int insnWidth, const DecodedInstruction* pDecInsn)
+{
+ static const float gSpecialTab[16] = {
+ -2.0f, -1.0f, -0.5f, -0.25f, -0.1f, 0.1f, 0.25f, 0.5f,
+ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 10.0f, 100.0f, 1000.0f
+ };
+ const u2* insns = pCode->insns;
+ int i;
+
+ printf("%06x:", ((u1*)insns - pDexFile->baseAddr) + insnIdx*2);
+ for (i = 0; i < 8; i++) {
+ if (i < insnWidth) {
+ if (i == 7) {
+ printf(" ... ");
+ } else {
+ /* print 16-bit value in little-endian order */
+ const u1* bytePtr = (const u1*) &insns[insnIdx+i];
+ printf(" %02x%02x", bytePtr[0], bytePtr[1]);
+ }
+ } else {
+ fputs(" ", stdout);
+ }
+ }
+
+ if (pDecInsn->opCode == OP_NOP) {
+ u2 instr = get2LE((const u1*) &insns[insnIdx]);
+ if (instr == kPackedSwitchSignature) {
+ printf("|%04x: packed-switch-data (%d units)",
+ insnIdx, insnWidth);
+ } else if (instr == kSparseSwitchSignature) {
+ printf("|%04x: sparse-switch-data (%d units)",
+ insnIdx, insnWidth);
+ } else if (instr == kArrayDataSignature) {
+ printf("|%04x: array-data (%d units)",
+ insnIdx, insnWidth);
+ } else {
+ printf("|%04x: nop // spacer", insnIdx);
+ }
+ } else {
+ printf("|%04x: %s", insnIdx, getOpcodeName(pDecInsn->opCode));
+ }
+
+ switch (dexGetInstrFormat(gInstrFormat, pDecInsn->opCode)) {
+ case kFmt10x: // op
+ break;
+ case kFmt12x: // op vA, vB
+ printf(" v%d, v%d", pDecInsn->vA, pDecInsn->vB);
+ break;
+ case kFmt11n: // op vA, #+B
+ printf(" v%d, #int %d // #%x",
+ pDecInsn->vA, (s4)pDecInsn->vB, (u1)pDecInsn->vB);
+ break;
+ case kFmt11x: // op vAA
+ printf(" v%d", pDecInsn->vA);
+ break;
+ case kFmt10t: // op +AA
+ case kFmt20t: // op +AAAA
+ {
+ s4 targ = (s4) pDecInsn->vA;
+ printf(" %04x // %c%04x",
+ insnIdx + targ,
+ (targ < 0) ? '-' : '+',
+ (targ < 0) ? -targ : targ);
+ }
+ break;
+ case kFmt22x: // op vAA, vBBBB
+ printf(" v%d, v%d", pDecInsn->vA, pDecInsn->vB);
+ break;
+ case kFmt21t: // op vAA, +BBBB
+ {
+ s4 targ = (s4) pDecInsn->vB;
+ printf(" v%d, %04x // %c%04x", pDecInsn->vA,
+ insnIdx + targ,
+ (targ < 0) ? '-' : '+',
+ (targ < 0) ? -targ : targ);
+ }
+ break;
+ case kFmt21s: // op vAA, #+BBBB
+ printf(" v%d, #int %d // #%x",
+ pDecInsn->vA, (s4)pDecInsn->vB, (u2)pDecInsn->vB);
+ break;
+ case kFmt21h: // op vAA, #+BBBB0000[00000000]
+ // The printed format varies a bit based on the actual opcode.
+ if (pDecInsn->opCode == OP_CONST_HIGH16) {
+ s4 value = pDecInsn->vB << 16;
+ printf(" v%d, #int %d // #%x",
+ pDecInsn->vA, value, (u2)pDecInsn->vB);
+ } else {
+ s8 value = ((s8) pDecInsn->vB) << 48;
+ printf(" v%d, #long %lld // #%x",
+ pDecInsn->vA, value, (u2)pDecInsn->vB);
+ }
+ break;
+ case kFmt21c: // op vAA, thing@BBBB
+ if (pDecInsn->opCode == OP_CONST_STRING) {
+ printf(" v%d, \"%s\" // string@%04x", pDecInsn->vA,
+ dexStringById(pDexFile, pDecInsn->vB), pDecInsn->vB);
+ } else if (pDecInsn->opCode == OP_CHECK_CAST ||
+ pDecInsn->opCode == OP_NEW_INSTANCE ||
+ pDecInsn->opCode == OP_CONST_CLASS)
+ {
+ printf(" v%d, %s // class@%04x", pDecInsn->vA,
+ getClassDescriptor(pDexFile, pDecInsn->vB), pDecInsn->vB);
+ } else /* OP_SGET* */ {
+ FieldMethodInfo fieldInfo;
+ if (getFieldInfo(pDexFile, pDecInsn->vB, &fieldInfo)) {
+ printf(" v%d, %s.%s:%s // field@%04x", pDecInsn->vA,
+ fieldInfo.classDescriptor, fieldInfo.name,
+ fieldInfo.signature, pDecInsn->vB);
+ } else {
+ printf(" v%d, ??? // field@%04x", pDecInsn->vA, pDecInsn->vB);
+ }
+ }
+ break;
+ case kFmt23x: // op vAA, vBB, vCC
+ printf(" v%d, v%d, v%d", pDecInsn->vA, pDecInsn->vB, pDecInsn->vC);
+ break;
+ case kFmt22b: // op vAA, vBB, #+CC
+ printf(" v%d, v%d, #int %d // #%02x",
+ pDecInsn->vA, pDecInsn->vB, (s4)pDecInsn->vC, (u1)pDecInsn->vC);
+ break;
+ case kFmt22t: // op vA, vB, +CCCC
+ {
+ s4 targ = (s4) pDecInsn->vC;
+ printf(" v%d, v%d, %04x // %c%04x", pDecInsn->vA, pDecInsn->vB,
+ insnIdx + targ,
+ (targ < 0) ? '-' : '+',
+ (targ < 0) ? -targ : targ);
+ }
+ break;
+ case kFmt22s: // op vA, vB, #+CCCC
+ printf(" v%d, v%d, #int %d // #%04x",
+ pDecInsn->vA, pDecInsn->vB, (s4)pDecInsn->vC, (u2)pDecInsn->vC);
+ break;
+ case kFmt22c: // op vA, vB, thing@CCCC
+ if (pDecInsn->opCode >= OP_IGET && pDecInsn->opCode <= OP_IPUT_SHORT) {
+ FieldMethodInfo fieldInfo;
+ if (getFieldInfo(pDexFile, pDecInsn->vC, &fieldInfo)) {
+ printf(" v%d, v%d, %s.%s:%s // field@%04x", pDecInsn->vA,
+ pDecInsn->vB, fieldInfo.classDescriptor, fieldInfo.name,
+ fieldInfo.signature, pDecInsn->vC);
+ } else {
+ printf(" v%d, v%d, ??? // field@%04x", pDecInsn->vA,
+ pDecInsn->vB, pDecInsn->vC);
+ }
+ } else {
+ printf(" v%d, v%d, %s // class@%04x",
+ pDecInsn->vA, pDecInsn->vB,
+ getClassDescriptor(pDexFile, pDecInsn->vC), pDecInsn->vC);
+ }
+ break;
+ case kFmt22cs: // [opt] op vA, vB, field offset CCCC
+ printf(" v%d, v%d, [obj+%04x]",
+ pDecInsn->vA, pDecInsn->vB, pDecInsn->vC);
+ break;
+ case kFmt30t:
+ printf(" #%08x", pDecInsn->vA);
+ break;
+ case kFmt31i: // op vAA, #+BBBBBBBB
+ {
+ /* this is often, but not always, a float */
+ union {
+ float f;
+ u4 i;
+ } conv;
+ conv.i = pDecInsn->vB;
+ printf(" v%d, #float %f // #%08x",
+ pDecInsn->vA, conv.f, pDecInsn->vB);
+ }
+ break;
+ case kFmt31c: // op vAA, thing@BBBBBBBB
+ printf(" v%d, \"%s\" // string@%08x", pDecInsn->vA,
+ dexStringById(pDexFile, pDecInsn->vB), pDecInsn->vB);
+ break;
+ case kFmt31t: // op vAA, offset +BBBBBBBB
+ printf(" v%d, %08x // +%08x",
+ pDecInsn->vA, insnIdx + pDecInsn->vB, pDecInsn->vB);
+ break;
+ case kFmt32x: // op vAAAA, vBBBB
+ printf(" v%d, v%d", pDecInsn->vA, pDecInsn->vB);
+ break;
+ case kFmt35c: // op vB, {vD, vE, vF, vG, vA}, thing@CCCC
+ {
+ /* NOTE: decoding of 35c doesn't quite match spec */
+ fputs(" {", stdout);
+ for (i = 0; i < (int) pDecInsn->vA; i++) {
+ if (i == 0)
+ printf("v%d", pDecInsn->arg[i]);
+ else
+ printf(", v%d", pDecInsn->arg[i]);
+ }
+ if (pDecInsn->opCode == OP_FILLED_NEW_ARRAY) {
+ printf("}, %s // class@%04x",
+ getClassDescriptor(pDexFile, pDecInsn->vB), pDecInsn->vB);
+ } else {
+ FieldMethodInfo methInfo;
+ if (getMethodInfo(pDexFile, pDecInsn->vB, &methInfo)) {
+ printf("}, %s.%s:%s // method@%04x",
+ methInfo.classDescriptor, methInfo.name,
+ methInfo.signature, pDecInsn->vB);
+ } else {
+ printf("}, ??? // method@%04x", pDecInsn->vB);
+ }
+ }
+ }
+ break;
+ case kFmt35ms: // [opt] invoke-virtual+super
+ case kFmt35fs: // [opt] invoke-interface
+ {
+ fputs(" {", stdout);
+ for (i = 0; i < (int) pDecInsn->vA; i++) {
+ if (i == 0)
+ printf("v%d", pDecInsn->arg[i]);
+ else
+ printf(", v%d", pDecInsn->arg[i]);
+ }
+ printf("}, [%04x] // vtable #%04x", pDecInsn->vB, pDecInsn->vB);
+ }
+ break;
+ case kFmt3rc: // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
+ {
+ /*
+ * This doesn't match the "dx" output when some of the args are
+ * 64-bit values -- dx only shows the first register.
+ */
+ fputs(" {", stdout);
+ for (i = 0; i < (int) pDecInsn->vA; i++) {
+ if (i == 0)
+ printf("v%d", pDecInsn->vC + i);
+ else
+ printf(", v%d", pDecInsn->vC + i);
+ }
+ if (pDecInsn->opCode == OP_FILLED_NEW_ARRAY_RANGE) {
+ printf("}, %s // class@%04x",
+ getClassDescriptor(pDexFile, pDecInsn->vB), pDecInsn->vB);
+ } else {
+ FieldMethodInfo methInfo;
+ if (getMethodInfo(pDexFile, pDecInsn->vB, &methInfo)) {
+ printf("}, %s.%s:%s // method@%04x",
+ methInfo.classDescriptor, methInfo.name,
+ methInfo.signature, pDecInsn->vB);
+ } else {
+ printf("}, ??? // method@%04x", pDecInsn->vB);
+ }
+ }
+ }
+ break;
+ case kFmt3rms: // [opt] invoke-virtual+super/range
+ case kFmt3rfs: // [opt] invoke-interface/range
+ {
+ /*
+ * This doesn't match the "dx" output when some of the args are
+ * 64-bit values -- dx only shows the first register.
+ */
+ fputs(" {", stdout);
+ for (i = 0; i < (int) pDecInsn->vA; i++) {
+ if (i == 0)
+ printf("v%d", pDecInsn->vC + i);
+ else
+ printf(", v%d", pDecInsn->vC + i);
+ }
+ printf("}, [%04x] // vtable #%04x", pDecInsn->vB, pDecInsn->vB);
+ }
+ break;
+ case kFmt3inline: // [opt] inline invoke
+ {
+#if 0
+ const InlineOperation* inlineOpsTable = dvmGetInlineOpsTable();
+ u4 tableLen = dvmGetInlineOpsTableLength();
+#endif
+
+ fputs(" {", stdout);
+ for (i = 0; i < (int) pDecInsn->vA; i++) {
+ if (i == 0)
+ printf("v%d", pDecInsn->arg[i]);
+ else
+ printf(", v%d", pDecInsn->arg[i]);
+ }
+#if 0
+ if (pDecInsn->vB < tableLen) {
+ printf("}, %s.%s:%s // inline #%04x",
+ inlineOpsTable[pDecInsn->vB].classDescriptor,
+ inlineOpsTable[pDecInsn->vB].methodName,
+ inlineOpsTable[pDecInsn->vB].methodSignature,
+ pDecInsn->vB);
+ } else {
+#endif
+ printf("}, [%04x] // inline #%04x", pDecInsn->vB, pDecInsn->vB);
+#if 0
+ }
+#endif
+ }
+ break;
+ case kFmt51l: // op vAA, #+BBBBBBBBBBBBBBBB
+ {
+ /* this is often, but not always, a double */
+ union {
+ double d;
+ u8 j;
+ } conv;
+ conv.j = pDecInsn->vB_wide;
+ printf(" v%d, #double %f // #%016llx",
+ pDecInsn->vA, conv.d, pDecInsn->vB_wide);
+ }
+ break;
+ case kFmtUnknown:
+ break;
+ default:
+ printf(" ???");
+ break;
+ }
+
+
+ putchar('\n');
+
+}
+
+/*
+ * Dump a bytecode disassembly.
+ */
+void dumpBytecodes(DexFile* pDexFile, const DexMethod* pDexMethod)
+{
+ const DexCode* pCode = dexGetCode(pDexFile, pDexMethod);
+ const u2* insns;
+ int insnIdx;
+ FieldMethodInfo methInfo;
+ int startAddr;
+ char* className = NULL;
+
+ assert(pCode->insnsSize > 0);
+ insns = pCode->insns;
+
+ getMethodInfo(pDexFile, pDexMethod->methodIdx, &methInfo);
+ startAddr = ((u1*)pCode - pDexFile->baseAddr);
+ className = descriptorToDot(methInfo.classDescriptor);
+
+ printf("%06x: |[%06x] %s.%s:%s\n",
+ startAddr, startAddr,
+ className, methInfo.name, methInfo.signature);
+
+ insnIdx = 0;
+ while (insnIdx < (int) pCode->insnsSize) {
+ int insnWidth;
+ OpCode opCode;
+ DecodedInstruction decInsn;
+ u2 instr;
+
+ instr = get2LE((const u1*)insns);
+ if (instr == kPackedSwitchSignature) {
+ insnWidth = 4 + get2LE((const u1*)(insns+1)) * 2;
+ } else if (instr == kSparseSwitchSignature) {
+ insnWidth = 2 + get2LE((const u1*)(insns+1)) * 4;
+ } else if (instr == kArrayDataSignature) {
+ int width = get2LE((const u1*)(insns+1));
+ int size = get2LE((const u1*)(insns+2)) |
+ (get2LE((const u1*)(insns+3))<<16);
+ // The plus 1 is to round up for odd size and width
+ insnWidth = 4 + ((size * width) + 1) / 2;
+ } else {
+ opCode = instr & 0xff;
+ insnWidth = dexGetInstrWidthAbs(gInstrWidth, opCode);
+ if (insnWidth == 0) {
+ fprintf(stderr,
+ "GLITCH: zero-width instruction at idx=0x%04x\n", insnIdx);
+ break;
+ }
+ }
+
+ dexDecodeInstruction(gInstrFormat, insns, &decInsn);
+ dumpInstruction(pDexFile, pCode, insnIdx, insnWidth, &decInsn);
+
+ insns += insnWidth;
+ insnIdx += insnWidth;
+ }
+
+ free(className);
+}
+
+/*
+ * Dump a "code" struct.
+ */
+void dumpCode(DexFile* pDexFile, const DexMethod* pDexMethod)
+{
+ const DexCode* pCode = dexGetCode(pDexFile, pDexMethod);
+
+ printf(" registers : %d\n", pCode->registersSize);
+ printf(" ins : %d\n", pCode->insSize);
+ printf(" outs : %d\n", pCode->outsSize);
+ printf(" insns size : %d 16-bit code units\n", pCode->insnsSize);
+
+ if (gOptions.disassemble)
+ dumpBytecodes(pDexFile, pDexMethod);
+
+ dumpCatches(pDexFile, pCode);
+ /* both of these are encoded in debug info */
+ dumpPositions(pDexFile, pCode, pDexMethod);
+ dumpLocals(pDexFile, pCode, pDexMethod);
+}
+
+/*
+ * Dump a method.
+ */
+void dumpMethod(DexFile* pDexFile, const DexMethod* pDexMethod, int i)
+{
+ const DexMethodId* pMethodId;
+ const char* backDescriptor;
+ const char* name;
+ char* typeDescriptor;
+ char* accessStr;
+
+ pMethodId = dexGetMethodId(pDexFile, pDexMethod->methodIdx);
+ name = dexStringById(pDexFile, pMethodId->nameIdx);
+ typeDescriptor = dexCopyDescriptorFromMethodId(pDexFile, pMethodId);
+
+ backDescriptor = dexStringByTypeIdx(pDexFile, pMethodId->classIdx);
+
+ accessStr = createAccessFlagStr(pDexMethod->accessFlags,
+ kAccessForMethod);
+
+ printf(" #%d : (in %s)\n", i, backDescriptor);
+ printf(" name : '%s'\n", name);
+ printf(" type : '%s'\n", typeDescriptor);
+ printf(" access : 0x%04x (%s)\n",
+ pDexMethod->accessFlags, accessStr);
+
+ if (pDexMethod->codeOff == 0) {
+ printf(" code : (none)\n");
+ } else {
+ printf(" code -\n");
+ dumpCode(pDexFile, pDexMethod);
+ }
+
+ if (gOptions.disassemble)
+ putchar('\n');
+
+ free(typeDescriptor);
+ free(accessStr);
+}
+
+/*
+ * Dump a static (class) field.
+ */
+void dumpSField(const DexFile* pDexFile, const DexField* pSField, int i)
+{
+ const DexFieldId* pFieldId;
+ const char* backDescriptor;
+ const char* name;
+ const char* typeDescriptor;
+ char* accessStr;
+
+ pFieldId = dexGetFieldId(pDexFile, pSField->fieldIdx);
+ name = dexStringById(pDexFile, pFieldId->nameIdx);
+ typeDescriptor = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
+ backDescriptor = dexStringByTypeIdx(pDexFile, pFieldId->classIdx);
+
+ accessStr = createAccessFlagStr(pSField->accessFlags, kAccessForField);
+
+ printf(" #%d : (in %s)\n", i, backDescriptor);
+ printf(" name : '%s'\n", name);
+ printf(" type : '%s'\n", typeDescriptor);
+ printf(" access : 0x%04x (%s)\n",
+ pSField->accessFlags, accessStr);
+
+ free(accessStr);
+}
+
+/*
+ * Dump an instance field.
+ */
+void dumpIField(const DexFile* pDexFile, const DexField* pIField, int i)
+{
+ const DexFieldId* pFieldId;
+ const char* backDescriptor;
+ const char* name;
+ const char* typeDescriptor;
+ char* accessStr;
+
+ pFieldId = dexGetFieldId(pDexFile, pIField->fieldIdx);
+ name = dexStringById(pDexFile, pFieldId->nameIdx);
+ typeDescriptor = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
+ backDescriptor = dexStringByTypeIdx(pDexFile, pFieldId->classIdx);
+
+ accessStr = createAccessFlagStr(pIField->accessFlags, kAccessForField);
+
+ printf(" #%d : (in %s)\n", i, backDescriptor);
+ printf(" name : '%s'\n", name);
+ printf(" type : '%s'\n", typeDescriptor);
+ printf(" access : 0x%04x (%s)\n",
+ pIField->accessFlags, accessStr);
+
+ free(accessStr);
+}
+
+/*
+ * Dump the class.
+ */
+void dumpClass(DexFile* pDexFile, int idx)
+{
+ const DexTypeList* pInterfaces;
+ const DexClassDef* pClassDef;
+ DexClassData* pClassData;
+ const u1* pEncodedData;
+ const char* fileName;
+ const char* classDescriptor;
+ const char* superclassDescriptor;
+ char* accessStr;
+ int i;
+
+ pClassDef = dexGetClassDef(pDexFile, idx);
+ printf("Class #%d -\n", idx);
+
+ pEncodedData = dexGetClassData(pDexFile, pClassDef);
+ pClassData = dexReadAndVerifyClassData(&pEncodedData, NULL);
+
+ if (pClassData == NULL) {
+ printf("Trouble reading class data\n");
+ return;
+ }
+
+ classDescriptor = dexStringByTypeIdx(pDexFile, pClassDef->classIdx);
+ printf(" Class descriptor : '%s'\n", classDescriptor);
+
+ accessStr = createAccessFlagStr(pClassDef->accessFlags, kAccessForClass);
+ printf(" Access flags : 0x%04x (%s)\n",
+ pClassDef->accessFlags, accessStr);
+
+ if (pClassDef->superclassIdx == kDexNoIndex)
+ superclassDescriptor = "(none)";
+ else {
+ superclassDescriptor =
+ dexStringByTypeIdx(pDexFile, pClassDef->superclassIdx);
+ printf(" Superclass : '%s'\n", superclassDescriptor);
+ }
+
+ printf(" Interfaces -\n");
+ pInterfaces = dexGetInterfacesList(pDexFile, pClassDef);
+ if (pInterfaces != NULL) {
+ for (i = 0; i < (int) pInterfaces->size; i++)
+ dumpInterface(pDexFile, dexGetTypeItem(pInterfaces, i), i);
+ }
+
+ printf(" Static fields -\n");
+ for (i = 0; i < (int) pClassData->header.staticFieldsSize; i++) {
+ dumpSField(pDexFile, &pClassData->staticFields[i], i);
+ }
+
+ printf(" Instance fields -\n");
+ for (i = 0; i < (int) pClassData->header.instanceFieldsSize; i++) {
+ dumpIField(pDexFile, &pClassData->instanceFields[i], i);
+ }
+
+ printf(" Direct methods -\n");
+ for (i = 0; i < (int) pClassData->header.directMethodsSize; i++) {
+ dumpMethod(pDexFile, &pClassData->directMethods[i], i);
+ }
+
+ printf(" Virtual methods -\n");
+ for (i = 0; i < (int) pClassData->header.virtualMethodsSize; i++) {
+ dumpMethod(pDexFile, &pClassData->virtualMethods[i], i);
+ }
+
+ // TODO: Annotations.
+
+ if (pClassDef->sourceFileIdx != kDexNoIndex)
+ fileName = dexStringById(pDexFile, pClassDef->sourceFileIdx);
+ else
+ fileName = "unknown";
+ printf(" source_file_idx : %d (%s)\n",
+ pClassDef->sourceFileIdx, fileName);
+
+ printf("\n");
+
+ free(pClassData);
+ free(accessStr);
+}
+
+/*
+ * Dump the requested sections of the file.
+ */
+void processDexFile(const char* fileName, DexFile* pDexFile)
+{
+ int i;
+
+ printf("Opened '%s', DEX version '%.3s'\n", fileName,
+ pDexFile->pHeader->magic +4);
+
+ if (gOptions.showFileHeaders)
+ dumpFileHeader(pDexFile);
+
+ for (i = 0; i < (int) pDexFile->pHeader->classDefsSize; i++) {
+ if (gOptions.showSectionHeaders)
+ dumpClassDef(pDexFile, i);
+
+ dumpClass(pDexFile, i);
+ }
+}
+
+
+/*
+ * Process one file.
+ */
+int process(const char* fileName)
+{
+ DexFile* pDexFile = NULL;
+ MemMapping map;
+ bool mapped = false;
+ int result = -1;
+
+ printf("Processing '%s'...\n", fileName);
+
+ if (dexOpenAndMap(fileName, gOptions.tempFileName, &map, false) != 0)
+ goto bail;
+ mapped = true;
+
+ pDexFile = dexFileParse(map.addr, map.length,
+ kDexParseVerifyChecksum | kDexParseContinueOnError);
+ if (pDexFile == NULL) {
+ fprintf(stderr, "ERROR: DEX parse failed\n");
+ goto bail;
+ }
+
+ processDexFile(fileName, pDexFile);
+
+ result = 0;
+
+bail:
+ if (mapped)
+ sysReleaseShmem(&map);
+ if (pDexFile != NULL)
+ dexFileFree(pDexFile);
+ return result;
+}
+
+
+/*
+ * Show usage.
+ */
+void usage(void)
+{
+ fprintf(stderr, "Copyright (C) 2007 The Android Open Source Project\n\n");
+ fprintf(stderr, "%s: [-d] [-f] [-h] [-t tempfile] dexfile...\n", gProgName);
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -d : disassemble code sections\n");
+ fprintf(stderr, " -f : display summary information from file header\n");
+ fprintf(stderr, " -h : display file header details\n");
+ fprintf(stderr, " -t : temp file name (defaults to /sdcard/dex-temp-*)\n");
+}
+
+/*
+ * Parse args.
+ *
+ * I'm not using getopt_long() because we may not have it in libc.
+ */
+int main(int argc, char* const argv[])
+{
+ bool wantUsage = false;
+ int ic;
+
+ memset(&gOptions, 0, sizeof(gOptions));
+
+ while (1) {
+ ic = getopt(argc, argv, "dfht:");
+ if (ic < 0)
+ break;
+
+ switch (ic) {
+ case 'd': // disassemble Dalvik instructions
+ gOptions.disassemble = true;
+ break;
+ case 'f': // dump outer file header
+ gOptions.showFileHeaders = true;
+ break;
+ case 'h': // dump section headers, i.e. all meta-data
+ gOptions.showSectionHeaders = true;
+ break;
+ case 't': // temp file, used when opening compressed Jar
+ gOptions.tempFileName = argv[optind];
+ break;
+ default:
+ wantUsage = true;
+ break;
+ }
+ }
+
+ if (optind == argc) {
+ fprintf(stderr, "%s: no file specified\n", gProgName);
+ wantUsage = true;
+ }
+
+ /* initialize some VM tables */
+ gInstrWidth = dexCreateInstrWidthTable();
+ gInstrFormat = dexCreateInstrFormatTable();
+
+ if (wantUsage) {
+ usage();
+ return 2;
+ }
+
+ while (optind < argc)
+ process(argv[optind++]);
+
+ free(gInstrWidth);
+ free(gInstrFormat);
+
+ return 0;
+}
View
330 dexdump/OpCodeNames.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.
+ */
+/*
+ * Table of Dalvik opcode names.
+ */
+#include "OpCodeNames.h"
+
+/*
+ * The following two lines work, but slashes and dashes both turn into
+ * underscores, and the strings are all upper case. The output is easier
+ * to read if we do the strings by hand (could probably write a
+ * post-processing function easily enough if maintenance becomes annoying).
+ */
+//#define H(_op) #_op
+//DEFINE_GOTO_TABLE(gOpNames)
+
+/*
+ * Dalvik opcode names.
+ */
+static const char* gOpNames[256] = {
+ /* 0x00 */
+ "nop",
+ "move",
+ "move/from16",
+ "move/16",
+ "move-wide",
+ "move-wide/from16",
+ "move-wide/16",
+ "move-object",
+ "move-object/from16",
+ "move-object/16",
+ "move-result",
+ "move-result-wide",
+ "move-result-object",
+ "move-exception",
+ "return-void",
+ "return",
+
+ /* 0x10 */
+ "return-wide",
+ "return-object",
+ "const/4",
+ "const/16",
+ "const",
+ "const/high16",
+ "const-wide/16",
+ "const-wide/32",
+ "const-wide",
+ "const-wide/high16",
+ "const-string",
+ "const-string/jumbo",
+ "const-class",
+ "monitor-enter",
+ "monitor-exit",
+ "check-cast",
+
+ /* 0x20 */
+ "instance-of",
+ "array-length",
+ "new-instance",
+ "new-array",
+ "filled-new-array",
+ "filled-new-array/range",
+ "fill-array-data",
+ "throw",
+ "goto",
+ "goto/16",
+ "goto/32",
+ "packed-switch",
+ "sparse-switch",
+ "cmpl-float",
+ "cmpg-float",
+ "cmpl-double",
+
+ /* 0x30 */
+ "cmpg-double",
+ "cmp-long",
+ "if-eq",
+ "if-ne",
+ "if-lt",
+ "if-ge",
+ "if-gt",
+ "if-le",
+ "if-eqz",
+ "if-nez",
+ "if-ltz",
+ "if-gez",
+ "if-gtz",
+ "if-lez",
+ "UNUSED",
+ "UNUSED",
+
+ /* 0x40 */
+ "UNUSED",
+ "UNUSED",
+ "UNUSED",
+ "UNUSED",
+ "aget",
+ "aget-wide",
+ "aget-object",
+ "aget-boolean",
+ "aget-byte",
+ "aget-char",
+ "aget-short",
+ "aput",
+ "aput-wide",
+ "aput-object",
+ "aput-boolean",
+ "aput-byte",
+
+ /* 0x50 */
+ "aput-char",
+ "aput-short",
+ "iget",
+ "iget-wide",
+ "iget-object",
+ "iget-boolean",
+ "iget-byte",
+ "iget-char",
+ "iget-short",
+ "iput",
+ "iput-wide",
+ "iput-object",
+ "iput-boolean",
+ "iput-byte",
+ "iput-char",
+ "iput-short",
+
+ /* 0x60 */
+ "sget",
+ "sget-wide",
+ "sget-object",
+ "sget-boolean",
+ "sget-byte",
+ "sget-char",
+ "sget-short",
+ "sput",
+ "sput-wide",
+ "sput-object",
+ "sput-boolean",
+ "sput-byte",
+ "sput-char",
+ "sput-short",
+ "invoke-virtual",
+ "invoke-super",
+
+ /* 0x70 */
+ "invoke-direct",
+ "invoke-static",
+ "invoke-interface",
+ "UNUSED",
+ "invoke-virtual/range",
+ "invoke-super/range",
+ "invoke-direct/range",
+ "invoke-static/range",
+ "invoke-interface/range",
+ "UNUSED",
+ "UNUSED",
+ "neg-int",
+ "not-int",
+ "neg-long",
+ "not-long",
+ "neg-float",
+
+ /* 0x80 */
+ "neg-double",
+ "int-to-long",
+ "int-to-float",
+ "int-to-double",
+ "long-to-int",
+ "long-to-float",
+ "long-to-double",
+ "float-to-int",
+ "float-to-long",
+ "float-to-double",
+ "double-to-int",
+ "double-to-long",
+ "double-to-float",
+ "int-to-byte",
+ "int-to-char",
+ "int-to-short",
+
+ /* 0x90 */
+ "add-int",
+ "sub-int",
+ "mul-int",
+ "div-int",
+ "rem-int",
+ "and-int",
+ "or-int",
+ "xor-int",
+ "shl-int",
+ "shr-int",
+ "ushr-int",
+ "add-long",
+ "sub-long",
+ "mul-long",
+ "div-long",
+ "rem-long",
+
+ /* 0xa0 */
+ "and-long",
+ "or-long",
+ "xor-long",
+ "shl-long",
+ "shr-long",
+ "ushr-long",
+ "add-float",
+ "sub-float",
+ "mul-float",
+ "div-float",
+ "rem-float",
+ "add-double",
+ "sub-double",
+ "mul-double",
+ "div-double",
+ "rem-double",
+
+ /* 0xb0 */
+ "add-int/2addr",
+ "sub-int/2addr",
+ "mul-int/2addr",
+ "div-int/2addr",
+ "rem-int/2addr",
+ "and-int/2addr",
+ "or-int/2addr",
+ "xor-int/2addr",
+ "shl-int/2addr",
+ "shr-int/2addr",
+ "ushr-int/2addr",
+ "add-long/2addr",
+ "sub-long/2addr",
+ "mul-long/2addr",
+ "div-long/2addr",
+ "rem-long/2addr",
+
+ /* 0xc0 */
+ "and-long/2addr",
+ "or-long/2addr",
+ "xor-long/2addr",
+ "shl-long/2addr",
+ "shr-long/2addr",
+ "ushr-long/2addr",
+ "add-float/2addr",
+ "sub-float/2addr",
+ "mul-float/2addr",
+ "div-float/2addr",
+ "rem-float/2addr",
+ "add-double/2addr",
+ "sub-double/2addr",
+ "mul-double/2addr",
+ "div-double/2addr",
+ "rem-double/2addr",
+
+ /* 0xd0 */
+ "add-int/lit16",
+ "rsub-int",
+ "mul-int/lit16",
+ "div-int/lit16",
+ "rem-int/lit16",
+ "and-int/lit16",
+ "or-int/lit16",
+ "xor-int/lit16",
+ "add-int/lit8",
+ "rsub-int/lit8",
+ "mul-int/lit8",
+ "div-int/lit8",
+ "rem-int/lit8",
+ "and-int/lit8",
+ "or-int/lit8",
+ "xor-int/lit8",
+
+ /* 0xe0 */
+ "shl-int/lit8",
+ "shr-int/lit8",
+ "ushr-int/lit8",
+ "UNUSED",