summaryrefslogtreecommitdiff
path: root/dexlayout/dexlayout.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dexlayout/dexlayout.cc')
-rw-r--r--dexlayout/dexlayout.cc88
1 files changed, 33 insertions, 55 deletions
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index a9ae55fd8b..2b30a1be08 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -30,6 +30,7 @@
#include <sstream>
#include <vector>
+#include "base/stringprintf.h"
#include "dex_ir_builder.h"
#include "dex_file-inl.h"
#include "dex_instruction-inl.h"
@@ -722,9 +723,11 @@ static void DumpLocalInfo(const dex_ir::CodeItem* code) {
static std::unique_ptr<char[]> IndexString(dex_ir::Header* header,
const Instruction* dec_insn,
size_t buf_size) {
+ static const uint32_t kInvalidIndex = std::numeric_limits<uint32_t>::max();
std::unique_ptr<char[]> buf(new char[buf_size]);
// Determine index and width of the string.
uint32_t index = 0;
+ uint32_t secondary_index = kInvalidIndex;
uint32_t width = 4;
switch (Instruction::FormatOf(dec_insn->Opcode())) {
// SOME NOT SUPPORTED:
@@ -748,6 +751,12 @@ static std::unique_ptr<char[]> IndexString(dex_ir::Header* header,
index = dec_insn->VRegC();
width = 4;
break;
+ case Instruction::k45cc:
+ case Instruction::k4rcc:
+ index = dec_insn->VRegB();
+ secondary_index = dec_insn->VRegH();
+ width = 4;
+ break;
default:
break;
} // switch
@@ -815,6 +824,24 @@ static std::unique_ptr<char[]> IndexString(dex_ir::Header* header,
// SOME NOT SUPPORTED:
// case Instruction::kIndexVaries:
// case Instruction::kIndexInlineMethod:
+ case Instruction::kIndexMethodAndProtoRef: {
+ std::string method("<method?>");
+ std::string proto("<proto?>");
+ if (index < header->GetCollections().MethodIdsSize()) {
+ dex_ir::MethodId* method_id = header->GetCollections().GetMethodId(index);
+ const char* name = method_id->Name()->Data();
+ std::string type_descriptor = GetSignatureForProtoId(method_id->Proto());
+ const char* back_descriptor = method_id->Class()->GetStringId()->Data();
+ method = StringPrintf("%s.%s:%s", back_descriptor, name, type_descriptor.c_str());
+ }
+ if (secondary_index < header->GetCollections().ProtoIdsSize()) {
+ dex_ir::ProtoId* proto_id = header->GetCollections().GetProtoId(secondary_index);
+ proto = GetSignatureForProtoId(proto_id);
+ }
+ outSize = snprintf(buf.get(), buf_size, "%s, %s // method@%0*x, proto@%0*x",
+ method.c_str(), proto.c_str(), width, index, width, secondary_index);
+ }
+ break;
default:
outSize = snprintf(buf.get(), buf_size, "<?>");
break;
@@ -984,7 +1011,8 @@ static void DumpInstruction(dex_ir::Header* header, const dex_ir::CodeItem* code
case Instruction::k32x: // op vAAAA, vBBBB
fprintf(out_file_, " v%d, v%d", dec_insn->VRegA(), dec_insn->VRegB());
break;
- case Instruction::k35c: { // op {vC, vD, vE, vF, vG}, thing@BBBB
+ case Instruction::k35c: // op {vC, vD, vE, vF, vG}, thing@BBBB
+ case Instruction::k45cc: { // op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH
// NOT SUPPORTED:
// case Instruction::k35ms: // [opt] invoke-virtual+super
// case Instruction::k35mi: // [opt] inline invoke
@@ -1001,7 +1029,8 @@ static void DumpInstruction(dex_ir::Header* header, const dex_ir::CodeItem* code
fprintf(out_file_, "}, %s", index_buf.get());
break;
}
- case Instruction::k3rc: // op {vCCCC .. v(CCCC+AA-1)}, thing@BBBB
+ case Instruction::k3rc: // op {vCCCC .. v(CCCC+AA-1)}, thing@BBBB
+ case Instruction::k4rcc: // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH
// NOT SUPPORTED:
// case Instruction::k3rms: // [opt] invoke-virtual+super/range
// case Instruction::k3rmi: // [opt] execute-inline/range
@@ -1257,49 +1286,6 @@ static void DumpIField(dex_ir::Header* header, uint32_t idx, uint32_t flags, int
}
/*
- * Dumping a CFG. Note that this will do duplicate work. utils.h doesn't expose the code-item
- * version, so the DumpMethodCFG code will have to iterate again to find it. But dexdump is a
- * tool, so this is not performance-critical.
- */
-
-static void DumpCFG(const DexFile* dex_file,
- uint32_t dex_method_idx,
- const DexFile::CodeItem* code) {
- if (code != nullptr) {
- std::ostringstream oss;
- DumpMethodCFG(dex_file, dex_method_idx, oss);
- fprintf(out_file_, "%s", oss.str().c_str());
- }
-}
-
-static void DumpCFG(const DexFile* dex_file, int idx) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(idx);
- const uint8_t* class_data = dex_file->GetClassData(class_def);
- if (class_data == nullptr) { // empty class such as a marker interface?
- return;
- }
- ClassDataItemIterator it(*dex_file, class_data);
- while (it.HasNextStaticField()) {
- it.Next();
- }
- while (it.HasNextInstanceField()) {
- it.Next();
- }
- while (it.HasNextDirectMethod()) {
- DumpCFG(dex_file,
- it.GetMemberIndex(),
- it.GetMethodCodeItem());
- it.Next();
- }
- while (it.HasNextVirtualMethod()) {
- DumpCFG(dex_file,
- it.GetMemberIndex(),
- it.GetMethodCodeItem());
- it.Next();
- }
-}
-
-/*
* Dumps the class.
*
* Note "idx" is a DexClassDef index, not a DexTypeId index.
@@ -1307,10 +1293,7 @@ static void DumpCFG(const DexFile* dex_file, int idx) {
* If "*last_package" is nullptr or does not match the current class' package,
* the value will be replaced with a newly-allocated string.
*/
-static void DumpClass(const DexFile* dex_file,
- dex_ir::Header* header,
- int idx,
- char** last_package) {
+static void DumpClass(dex_ir::Header* header, int idx, char** last_package) {
dex_ir::ClassDef* class_def = header->GetCollections().GetClassDef(idx);
// Omitting non-public class.
if (options_.exports_only_ && (class_def->GetAccessFlags() & kAccPublic) == 0) {
@@ -1325,11 +1308,6 @@ static void DumpClass(const DexFile* dex_file,
DumpClassAnnotations(header, idx);
}
- if (options_.show_cfg_) {
- DumpCFG(dex_file, idx);
- return;
- }
-
// For the XML output, show the package name. Ideally we'd gather
// up the classes, sort them, and dump them alphabetically so the
// package name wouldn't jump around, but that's not a great plan
@@ -1532,7 +1510,7 @@ static void ProcessDexFile(const char* file_name, const DexFile* dex_file, size_
char* package = nullptr;
const uint32_t class_defs_size = header->GetCollections().ClassDefsSize();
for (uint32_t i = 0; i < class_defs_size; i++) {
- DumpClass(dex_file, header.get(), i, &package);
+ DumpClass(header.get(), i, &package);
} // for
// Free the last package allocated.