diff options
Diffstat (limited to 'dexlayout/dexlayout.cc')
| -rw-r--r-- | dexlayout/dexlayout.cc | 88 |
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. |