art/oatdump/oatdump.cc
1475int main(int argc,char** argv) {
1476 return art::oatdump(argc, argv);
1477}
1351 static int oatdump(int argc,char** argv) {
1414 if (oat_filename != NULL) {
1415 OatFile* oat_file =
1416 OatFile::Open(oat_filename,oat_filename, NULL, false);
1417 if (oat_file == NULL) {
1418 fprintf(stderr, "Failed to open oatfile from %s\n", oat_filename);
1419 return EXIT_FAILURE;
1420 }
1421 OatDumperoat_dumper(*host_prefix.get(), *oat_file);
1422 oat_dumper.Dump(*os);
1423 return EXIT_SUCCESS;
1424 }
107 void Dump(std::ostream& os) {
108 const OatHeader& oat_header = oat_file_.GetOatHeader();
109
110 os << "MAGIC:\n";
111 os << oat_header.GetMagic() << "\n\n";
112
113 os << "CHECKSUM:\n";
114 os << StringPrintf("0x%08x\n\n",oat_header.GetChecksum());
115
116 os << "INSTRUCTION SET:\n";
117 os << oat_header.GetInstructionSet() << "\n\n";
118
119 os << "DEX FILE COUNT:\n";
120 os << oat_header.GetDexFileCount() << "\n\n";
121
122 os << "EXECUTABLE OFFSET:\n";
123 os << StringPrintf("0x%08x\n\n",oat_header.GetExecutableOffset());
124
125 os << "IMAGE FILE LOCATION OAT CHECKSUM:\n";
126 os << StringPrintf("0x%08x\n\n",oat_header.GetImageFileLocationOatChecksum());
127
128 os << "IMAGE FILE LOCATION OAT BEGIN:\n";
129 os << StringPrintf("0x%08x\n\n",oat_header.GetImageFileLocationOatDataBegin());
130
131 os << "IMAGE FILE LOCATION:\n";
132 const std::stringimage_file_location(oat_header.GetImageFileLocation());
133 os << image_file_location;
134 if (!image_file_location.empty() && !host_prefix_.empty()) {
135 os << " (" << host_prefix_ <<image_file_location << ")";
136 }
137 os << "\n\n";
138
139 os << "BEGIN:\n";
140 os << reinterpret_cast<const void*>(oat_file_.Begin())<< "\n\n";
141
142 os << "END:\n";
143 os << reinterpret_cast<const void*>(oat_file_.End())<< "\n\n";
144
145 os << std::flush;
146
147 for (size_t i = 0; i < oat_dex_files_.size(); i++) {
148 const OatFile::OatDexFile* oat_dex_file = oat_dex_files_[i];
149 CHECK(oat_dex_file != NULL);
150 DumpOatDexFile(os, *oat_dex_file);
151 }
152 }
244 void DumpOatDexFile(std::ostream& os, const OatFile::OatDexFile&oat_dex_file){
245 os << "OAT DEX FILE:\n";
246 os << StringPrintf("location: %s\n",oat_dex_file.GetDexFileLocation().c_str());
247 os << StringPrintf("checksum: 0x%08x\n",oat_dex_file.GetDexFileLocationChecksum());
248 UniquePtr<const DexFile> dex_file(oat_dex_file.OpenDexFile());
249 if (dex_file.get() == NULL) {
250 os << "NOT FOUND\n\n";
251 return;
252 }
253 for (size_t class_def_index = 0; class_def_index <dex_file->NumClassDefs(); class_def_index++) {
254 const DexFile::ClassDef& class_def =dex_file->GetClassDef(class_def_index);
255 const char* descriptor = dex_file->GetClassDescriptor(class_def);
256 UniquePtr<const OatFile::OatClass>oat_class(oat_dex_file.GetOatClass(class_def_index));
257 CHECK(oat_class.get() != NULL);
258 os << StringPrintf("%zd: %s (type_idx=%d) (",class_def_index, descriptor, class_def.class_idx_)
259 << oat_class->GetStatus() << ")\n";
260 Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
261 std::ostream indented_os(&indent_filter);
262 DumpOatClass(indented_os,*oat_class.get(), *(dex_file.get()), class_def);
263 }
264
265 os << std::flush;
266 }
277 void DumpOatClass(std::ostream& os, const OatFile::OatClass&oat_class, const DexFile& dex_file,
278 constDexFile::ClassDef& class_def) {
279 const byte* class_data = dex_file.GetClassData(class_def);
280 if (class_data == NULL) { //empty class such as a marker interface?
281 return;
282 }
283 ClassDataItemIterator it(dex_file, class_data);
284 SkipAllFields(it);
285 uint32_t class_method_idx = 0;
286 while (it.HasNextDirectMethod()) {
287 const OatFile::OatMethod oat_method =oat_class.GetOatMethod(class_method_idx);
288 DumpOatMethod(os, class_def,class_method_idx, oat_method, dex_file,
289 it.GetMemberIndex(),it.GetMethodCodeItem(), it.GetMemberAccessFlags());
290 class_method_idx++;
291 it.Next();
292 }
293 while (it.HasNextVirtualMethod()) {
294 const OatFile::OatMethod oat_method =oat_class.GetOatMethod(class_method_idx);
295 DumpOatMethod(os, class_def,class_method_idx, oat_method, dex_file,
296 it.GetMemberIndex(),it.GetMethodCodeItem(),it.GetMemberAccessFlags());
297 class_method_idx++;
298 it.Next();
299 }
300 DCHECK(!it.HasNext());
301 os << std::flush;
302 }
304 void DumpOatMethod(std::ostream& os, const DexFile::ClassDef&class_def,
305 uint32_tclass_method_index,
306 const OatFile::OatMethod& oat_method,const DexFile& dex_file,
307 uint32_t dex_method_idx,const DexFile::CodeItem* code_item,
308 uint32_tmethod_access_flags) {
309 os << StringPrintf("%d: %s (dex_method_idx=%d)\n",
310 class_method_index,PrettyMethod(dex_method_idx, dex_file, true).c_str(),
311 dex_method_idx);
312 Indenter indent1_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
313 std::ostream indent1_os(&indent1_filter);
314 {
315 indent1_os << "DEX CODE:\n";
316 Indenter indent2_filter(indent1_os.rdbuf(), kIndentChar,kIndentBy1Count);
317 std::ostream indent2_os(&indent2_filter);
318 DumpDexCode(indent2_os, dex_file,code_item);
319 }
605 void DumpDexCode(std::ostream& os, const DexFile& dex_file,const DexFile::CodeItem* code_item) {
606 if (code_item != NULL) {
607 size_t i = 0;
608 while (i < code_item->insns_size_in_code_units_) {
609 const Instruction* instruction =Instruction::At(&code_item->insns_[i]);
610 os << StringPrintf("0x%04zx: %s\n", i, instruction->DumpString(&dex_file).c_str());
611 i += instruction->SizeInCodeUnits();
612 }
613 }
614 }
386 std::stringInstruction::DumpString(const DexFile* file) const {
387 std::ostringstream os;
388 const char* opcode =kInstructionNames[Opcode()];
389 switch (FormatOf(Opcode())) {
390 case k10x: os << opcode; break;
546 casek35c: {
547 uint32_t arg[5];
548 GetArgs(arg);
549 switch (Opcode()) {
550 case INVOKE_VIRTUAL:
551 case INVOKE_SUPER:
552 case INVOKE_DIRECT:
553 case INVOKE_STATIC:
554 case INVOKE_INTERFACE:
555 if (file != NULL) {
556 os << opcode << "{";
557 uint32_t method_idx = VRegB_35c();
558 for (size_t i = 0; i <VRegA_35c(); ++i) {
559 if (i != 0) {
560 os << ", ";
561 }
562 os << "v"<< arg[i];
563 }
564 os << "}, "<< PrettyMethod(method_idx, *file) << " // method@"<< method_idx;
565 break;
566 } // else fall-through
567 case INVOKE_VIRTUAL_QUICK:
568 if (file != NULL) {
569 os << opcode << "{";
570 uint32_t method_idx = VRegB_35c();
571 for (size_t i = 0; i <VRegA_35c(); ++i) {
572 if (i != 0) {
573 os << ", ";
574 }
575 os << "v"<< arg[i];
576 }
577 os << "}, // vtable@" << method_idx;
578 break;
579 } // else fall-through
580 default:
581 os << opcode << "{v" << arg[0] << ", v" << arg[1] <<", v" << arg[2]
582 << ",v" << arg[3] << ", v" << arg[4] <<"}, thing@" << VRegB_35c();
583 break;
584 }
585 break;
586 }
art//runtime/utils.cc
379 std::string PrettyMethod(uint32_tmethod_idx, const DexFile& dex_file, bool with_signature) {
380 if(method_idx >= dex_file.NumMethodIds()) {
381 return StringPrintf("<<invalid-method-idx-%d>>",method_idx);
382 }
383 const DexFile::MethodId& method_id =dex_file.GetMethodId(method_idx);
384 std::stringresult(PrettyDescriptor(dex_file.GetMethodDeclaringClassDescriptor(method_id)));
385 result += '.';
386 result += dex_file.GetMethodName(method_id);
387 if(with_signature) {
388 std::string signature(dex_file.GetMethodSignature(method_id));
389 if (signature == "<no signature>") {
390 return result + signature;
391 }
392 result = PrettyReturnType(signature.c_str()) + " " + result +PrettyArguments(signature.c_str());
393 }
394 return result;
395 }