LEFT | RIGHT |
1 // Copyright (c) 2010 Google Inc. | 1 // Copyright (c) 2010 Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 #include <string.h> | 42 #include <string.h> |
43 #include <time.h> | 43 #include <time.h> |
44 | 44 |
45 #ifdef _WIN32 | 45 #ifdef _WIN32 |
46 #include <io.h> | 46 #include <io.h> |
47 #define PRIx64 "llx" | 47 #define PRIx64 "llx" |
48 #define PRIx32 "lx" | 48 #define PRIx32 "lx" |
49 #define snprintf _snprintf | 49 #define snprintf _snprintf |
50 #else // _WIN32 | 50 #else // _WIN32 |
51 #include <unistd.h> | 51 #include <unistd.h> |
52 #define O_BINARY 0 | |
53 #endif // _WIN32 | 52 #endif // _WIN32 |
54 | 53 |
55 #include <fstream> | 54 #include <fstream> |
56 #include <iostream> | 55 #include <iostream> |
57 #include <limits> | 56 #include <limits> |
58 #include <map> | 57 #include <map> |
59 #include <vector> | 58 #include <vector> |
60 | 59 |
61 #include "processor/range_map-inl.h" | 60 #include "processor/range_map-inl.h" |
62 | 61 |
63 #include "common/scoped_ptr.h" | 62 #include "common/scoped_ptr.h" |
| 63 #include "google_breakpad/processor/dump_context.h" |
64 #include "processor/basic_code_module.h" | 64 #include "processor/basic_code_module.h" |
65 #include "processor/basic_code_modules.h" | 65 #include "processor/basic_code_modules.h" |
66 #include "processor/logging.h" | 66 #include "processor/logging.h" |
67 | 67 |
68 namespace google_breakpad { | 68 namespace google_breakpad { |
69 | 69 |
70 | 70 |
71 using std::istream; | 71 using std::istream; |
72 using std::ifstream; | 72 using std::ifstream; |
73 using std::numeric_limits; | 73 using std::numeric_limits; |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 return string(timestr); | 384 return string(timestr); |
385 } | 385 } |
386 | 386 |
387 | 387 |
388 // | 388 // |
389 // MinidumpObject | 389 // MinidumpObject |
390 // | 390 // |
391 | 391 |
392 | 392 |
393 MinidumpObject::MinidumpObject(Minidump* minidump) | 393 MinidumpObject::MinidumpObject(Minidump* minidump) |
394 : minidump_(minidump), | 394 : DumpObject(), |
395 valid_(false) { | 395 minidump_(minidump) { |
396 } | 396 } |
397 | 397 |
398 | 398 |
399 // | 399 // |
400 // MinidumpStream | 400 // MinidumpStream |
401 // | 401 // |
402 | 402 |
403 | 403 |
404 MinidumpStream::MinidumpStream(Minidump* minidump) | 404 MinidumpStream::MinidumpStream(Minidump* minidump) |
405 : MinidumpObject(minidump) { | 405 : MinidumpObject(minidump) { |
406 } | 406 } |
407 | 407 |
408 | 408 |
409 // | 409 // |
410 // MinidumpContext | 410 // MinidumpContext |
411 // | 411 // |
412 | 412 |
413 | 413 |
414 MinidumpContext::MinidumpContext(Minidump* minidump) | 414 MinidumpContext::MinidumpContext(Minidump* minidump) |
415 : MinidumpStream(minidump), | 415 : DumpContext(), |
416 context_(), | 416 minidump_(minidump) { |
417 context_flags_(0) { | 417 } |
418 } | |
419 | |
420 | 418 |
421 MinidumpContext::~MinidumpContext() { | 419 MinidumpContext::~MinidumpContext() { |
422 FreeContext(); | 420 } |
423 } | |
424 | |
425 | 421 |
426 bool MinidumpContext::Read(uint32_t expected_size) { | 422 bool MinidumpContext::Read(uint32_t expected_size) { |
427 valid_ = false; | 423 valid_ = false; |
428 | 424 |
429 // Certain raw context types are currently assumed to have unique sizes. | 425 // Certain raw context types are currently assumed to have unique sizes. |
430 if (!IsContextSizeUnique(sizeof(MDRawContextAMD64))) { | 426 if (!IsContextSizeUnique(sizeof(MDRawContextAMD64))) { |
431 BPLOG(ERROR) << "sizeof(MDRawContextAMD64) cannot match the size of any " | 427 BPLOG(ERROR) << "sizeof(MDRawContextAMD64) cannot match the size of any " |
432 << "other raw context"; | 428 << "other raw context"; |
433 return false; | 429 return false; |
434 } | 430 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 ++vr_index) | 536 ++vr_index) |
541 Swap(&context_amd64->vector_register[vr_index]); | 537 Swap(&context_amd64->vector_register[vr_index]); |
542 Swap(&context_amd64->vector_control); | 538 Swap(&context_amd64->vector_control); |
543 Swap(&context_amd64->debug_control); | 539 Swap(&context_amd64->debug_control); |
544 Swap(&context_amd64->last_branch_to_rip); | 540 Swap(&context_amd64->last_branch_to_rip); |
545 Swap(&context_amd64->last_branch_from_rip); | 541 Swap(&context_amd64->last_branch_from_rip); |
546 Swap(&context_amd64->last_exception_to_rip); | 542 Swap(&context_amd64->last_exception_to_rip); |
547 Swap(&context_amd64->last_exception_from_rip); | 543 Swap(&context_amd64->last_exception_from_rip); |
548 } | 544 } |
549 | 545 |
550 context_flags_ = context_amd64->context_flags; | 546 SetContextFlags(context_amd64->context_flags); |
551 | 547 |
552 context_.amd64 = context_amd64.release(); | 548 SetContextAMD64(context_amd64.release()); |
553 } else if (expected_size == sizeof(MDRawContextPPC64)) { | 549 } else if (expected_size == sizeof(MDRawContextPPC64)) { |
554 // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext | 550 // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext |
555 // in the else case have 32 bits |context_flags|, so special case it here. | 551 // in the else case have 32 bits |context_flags|, so special case it here. |
556 uint64_t context_flags; | 552 uint64_t context_flags; |
557 if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { | 553 if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { |
558 BPLOG(ERROR) << "MinidumpContext could not read context flags"; | 554 BPLOG(ERROR) << "MinidumpContext could not read context flags"; |
559 return false; | 555 return false; |
560 } | 556 } |
561 if (minidump_->swap()) | 557 if (minidump_->swap()) |
562 Swap(&context_flags); | 558 Swap(&context_flags); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; | 622 vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; |
627 ++vr_index) { | 623 ++vr_index) { |
628 Normalize128(&context_ppc64->vector_save.save_vr[vr_index], true); | 624 Normalize128(&context_ppc64->vector_save.save_vr[vr_index], true); |
629 Swap(&context_ppc64->vector_save.save_vr[vr_index]); | 625 Swap(&context_ppc64->vector_save.save_vr[vr_index]); |
630 } | 626 } |
631 Swap(&context_ppc64->vector_save.save_vscr); | 627 Swap(&context_ppc64->vector_save.save_vscr); |
632 // Don't swap the padding fields in vector_save. | 628 // Don't swap the padding fields in vector_save. |
633 Swap(&context_ppc64->vector_save.save_vrvalid); | 629 Swap(&context_ppc64->vector_save.save_vrvalid); |
634 } | 630 } |
635 | 631 |
636 context_flags_ = static_cast<uint32_t>(context_ppc64->context_flags); | 632 SetContextFlags(static_cast<uint32_t>(context_ppc64->context_flags)); |
637 | 633 |
638 // Check for data loss when converting context flags from uint64_t into | 634 // Check for data loss when converting context flags from uint64_t into |
639 // uint32_t | 635 // uint32_t |
640 if (static_cast<uint64_t>(context_flags_) != | 636 if (static_cast<uint64_t>(GetContextFlags()) != |
641 context_ppc64->context_flags) { | 637 context_ppc64->context_flags) { |
642 BPLOG(ERROR) << "Data loss detected when converting PPC64 context_flags"; | 638 BPLOG(ERROR) << "Data loss detected when converting PPC64 context_flags"; |
643 return false; | 639 return false; |
644 } | 640 } |
645 | 641 |
646 context_.ppc64 = context_ppc64.release(); | 642 SetContextPPC64(context_ppc64.release()); |
647 } else if (expected_size == sizeof(MDRawContextARM64)) { | 643 } else if (expected_size == sizeof(MDRawContextARM64)) { |
648 // |context_flags| of MDRawContextARM64 is 64 bits, but other MDRawContext | 644 // |context_flags| of MDRawContextARM64 is 64 bits, but other MDRawContext |
649 // in the else case have 32 bits |context_flags|, so special case it here. | 645 // in the else case have 32 bits |context_flags|, so special case it here. |
650 uint64_t context_flags; | 646 uint64_t context_flags; |
651 | 647 |
652 BPLOG(INFO) << "MinidumpContext: looks like ARM64 context"; | 648 BPLOG(INFO) << "MinidumpContext: looks like ARM64 context"; |
653 | 649 |
654 if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { | 650 if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { |
655 BPLOG(ERROR) << "MinidumpContext could not read context flags"; | 651 BPLOG(ERROR) << "MinidumpContext could not read context flags"; |
656 return false; | 652 return false; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 for (unsigned int fpr_index = 0; | 707 for (unsigned int fpr_index = 0; |
712 fpr_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT; | 708 fpr_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT; |
713 ++fpr_index) { | 709 ++fpr_index) { |
714 // While ARM64 is bi-endian, iOS (currently the only platform | 710 // While ARM64 is bi-endian, iOS (currently the only platform |
715 // for which ARM64 support has been brought up) uses ARM64 exclusively | 711 // for which ARM64 support has been brought up) uses ARM64 exclusively |
716 // in little-endian mode. | 712 // in little-endian mode. |
717 Normalize128(&context_arm64->float_save.regs[fpr_index], false); | 713 Normalize128(&context_arm64->float_save.regs[fpr_index], false); |
718 Swap(&context_arm64->float_save.regs[fpr_index]); | 714 Swap(&context_arm64->float_save.regs[fpr_index]); |
719 } | 715 } |
720 } | 716 } |
721 context_flags_ = static_cast<uint32_t>(context_arm64->context_flags); | 717 SetContextFlags(static_cast<uint32_t>(context_arm64->context_flags)); |
722 | 718 |
723 // Check for data loss when converting context flags from uint64_t into | 719 // Check for data loss when converting context flags from uint64_t into |
724 // uint32_t | 720 // uint32_t |
725 if (static_cast<uint64_t>(context_flags_) != | 721 if (static_cast<uint64_t>(GetContextFlags()) != |
726 context_arm64->context_flags) { | 722 context_arm64->context_flags) { |
727 BPLOG(ERROR) << "Data loss detected when converting ARM64 context_flags"; | 723 BPLOG(ERROR) << "Data loss detected when converting ARM64 context_flags"; |
728 return false; | 724 return false; |
729 } | 725 } |
730 | 726 |
731 context_.arm64 = context_arm64.release(); | 727 SetContextARM64(context_arm64.release()); |
732 } else { | 728 } else { |
733 uint32_t context_flags; | 729 uint32_t context_flags; |
734 if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { | 730 if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) { |
735 BPLOG(ERROR) << "MinidumpContext could not read context flags"; | 731 BPLOG(ERROR) << "MinidumpContext could not read context flags"; |
736 return false; | 732 return false; |
737 } | 733 } |
738 if (minidump_->swap()) | 734 if (minidump_->swap()) |
739 Swap(&context_flags); | 735 Swap(&context_flags); |
740 | 736 |
741 uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; | 737 uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 Swap(&context_x86->ebp); | 822 Swap(&context_x86->ebp); |
827 Swap(&context_x86->eip); | 823 Swap(&context_x86->eip); |
828 Swap(&context_x86->cs); | 824 Swap(&context_x86->cs); |
829 Swap(&context_x86->eflags); | 825 Swap(&context_x86->eflags); |
830 Swap(&context_x86->esp); | 826 Swap(&context_x86->esp); |
831 Swap(&context_x86->ss); | 827 Swap(&context_x86->ss); |
832 // context_x86->extended_registers[] contains 8-bit quantities and | 828 // context_x86->extended_registers[] contains 8-bit quantities and |
833 // does not need to be swapped. | 829 // does not need to be swapped. |
834 } | 830 } |
835 | 831 |
836 context_.x86 = context_x86.release(); | 832 SetContextX86(context_x86.release()); |
837 | 833 |
838 break; | 834 break; |
839 } | 835 } |
840 | 836 |
841 case MD_CONTEXT_PPC: { | 837 case MD_CONTEXT_PPC: { |
842 if (expected_size != sizeof(MDRawContextPPC)) { | 838 if (expected_size != sizeof(MDRawContextPPC)) { |
843 BPLOG(ERROR) << "MinidumpContext ppc size mismatch, " << | 839 BPLOG(ERROR) << "MinidumpContext ppc size mismatch, " << |
844 expected_size << " != " << sizeof(MDRawContextPPC); | 840 expected_size << " != " << sizeof(MDRawContextPPC); |
845 return false; | 841 return false; |
846 } | 842 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 for (unsigned int vr_index = 0; | 898 for (unsigned int vr_index = 0; |
903 vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; | 899 vr_index < MD_VECTORSAVEAREA_PPC_VR_COUNT; |
904 ++vr_index) { | 900 ++vr_index) { |
905 Swap(&context_ppc->vector_save.save_vr[vr_index]); | 901 Swap(&context_ppc->vector_save.save_vr[vr_index]); |
906 } | 902 } |
907 Swap(&context_ppc->vector_save.save_vscr); | 903 Swap(&context_ppc->vector_save.save_vscr); |
908 // Don't swap the padding fields in vector_save. | 904 // Don't swap the padding fields in vector_save. |
909 Swap(&context_ppc->vector_save.save_vrvalid); | 905 Swap(&context_ppc->vector_save.save_vrvalid); |
910 } | 906 } |
911 | 907 |
912 context_.ppc = context_ppc.release(); | 908 SetContextPPC(context_ppc.release()); |
913 | 909 |
914 break; | 910 break; |
915 } | 911 } |
916 | 912 |
917 case MD_CONTEXT_SPARC: { | 913 case MD_CONTEXT_SPARC: { |
918 if (expected_size != sizeof(MDRawContextSPARC)) { | 914 if (expected_size != sizeof(MDRawContextSPARC)) { |
919 BPLOG(ERROR) << "MinidumpContext sparc size mismatch, " << | 915 BPLOG(ERROR) << "MinidumpContext sparc size mismatch, " << |
920 expected_size << " != " << sizeof(MDRawContextSPARC); | 916 expected_size << " != " << sizeof(MDRawContextSPARC); |
921 return false; | 917 return false; |
922 } | 918 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 Swap(&context_sparc->asi); | 954 Swap(&context_sparc->asi); |
959 Swap(&context_sparc->fprs); | 955 Swap(&context_sparc->fprs); |
960 for (unsigned int fpr_index = 0; | 956 for (unsigned int fpr_index = 0; |
961 fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; | 957 fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; |
962 ++fpr_index) { | 958 ++fpr_index) { |
963 Swap(&context_sparc->float_save.regs[fpr_index]); | 959 Swap(&context_sparc->float_save.regs[fpr_index]); |
964 } | 960 } |
965 Swap(&context_sparc->float_save.filler); | 961 Swap(&context_sparc->float_save.filler); |
966 Swap(&context_sparc->float_save.fsr); | 962 Swap(&context_sparc->float_save.fsr); |
967 } | 963 } |
968 context_.ctx_sparc = context_sparc.release(); | 964 SetContextSPARC(context_sparc.release()); |
969 | 965 |
970 break; | 966 break; |
971 } | 967 } |
972 | 968 |
973 case MD_CONTEXT_ARM: { | 969 case MD_CONTEXT_ARM: { |
974 if (expected_size != sizeof(MDRawContextARM)) { | 970 if (expected_size != sizeof(MDRawContextARM)) { |
975 BPLOG(ERROR) << "MinidumpContext arm size mismatch, " << | 971 BPLOG(ERROR) << "MinidumpContext arm size mismatch, " << |
976 expected_size << " != " << sizeof(MDRawContextARM); | 972 expected_size << " != " << sizeof(MDRawContextARM); |
977 return false; | 973 return false; |
978 } | 974 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; | 1009 fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; |
1014 ++fpr_index) { | 1010 ++fpr_index) { |
1015 Swap(&context_arm->float_save.regs[fpr_index]); | 1011 Swap(&context_arm->float_save.regs[fpr_index]); |
1016 } | 1012 } |
1017 for (unsigned int fpe_index = 0; | 1013 for (unsigned int fpe_index = 0; |
1018 fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; | 1014 fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; |
1019 ++fpe_index) { | 1015 ++fpe_index) { |
1020 Swap(&context_arm->float_save.extra[fpe_index]); | 1016 Swap(&context_arm->float_save.extra[fpe_index]); |
1021 } | 1017 } |
1022 } | 1018 } |
1023 context_.arm = context_arm.release(); | 1019 SetContextARM(context_arm.release()); |
1024 | 1020 |
1025 break; | 1021 break; |
1026 } | 1022 } |
1027 | 1023 |
1028 case MD_CONTEXT_MIPS: { | 1024 case MD_CONTEXT_MIPS: { |
1029 if (expected_size != sizeof(MDRawContextMIPS)) { | 1025 if (expected_size != sizeof(MDRawContextMIPS)) { |
1030 BPLOG(ERROR) << "MinidumpContext MIPS size mismatch, " | 1026 BPLOG(ERROR) << "MinidumpContext MIPS size mismatch, " |
1031 << expected_size | 1027 << expected_size |
1032 << " != " | 1028 << " != " |
1033 << sizeof(MDRawContextMIPS); | 1029 << sizeof(MDRawContextMIPS); |
1034 return false; | 1030 return false; |
1035 } | 1031 } |
1036 | 1032 |
1037 scoped_ptr<MDRawContextMIPS> context_mips(new MDRawContextMIPS()); | 1033 scoped_ptr<MDRawContextMIPS> context_mips(new MDRawContextMIPS()); |
1038 | 1034 |
1039 // Set the context_flags member, which has already been read, and | 1035 // Set the context_flags member, which has already been read, and |
1040 // read the rest of the structure beginning with the first member | 1036 // read the rest of the structure beginning with the first member |
1041 // after context_flags. | 1037 // after context_flags. |
1042 context_mips->context_flags = context_flags; | 1038 context_mips->context_flags = context_flags; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1078 Swap(&context_mips->status); | 1074 Swap(&context_mips->status); |
1079 Swap(&context_mips->cause); | 1075 Swap(&context_mips->cause); |
1080 for (int fpr_index = 0; | 1076 for (int fpr_index = 0; |
1081 fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; | 1077 fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; |
1082 ++fpr_index) { | 1078 ++fpr_index) { |
1083 Swap(&context_mips->float_save.regs[fpr_index]); | 1079 Swap(&context_mips->float_save.regs[fpr_index]); |
1084 } | 1080 } |
1085 Swap(&context_mips->float_save.fpcsr); | 1081 Swap(&context_mips->float_save.fpcsr); |
1086 Swap(&context_mips->float_save.fir); | 1082 Swap(&context_mips->float_save.fir); |
1087 } | 1083 } |
1088 context_.ctx_mips = context_mips.release(); | 1084 SetContextMIPS(context_mips.release()); |
1089 | 1085 |
1090 break; | 1086 break; |
1091 } | 1087 } |
1092 | 1088 |
1093 default: { | 1089 default: { |
1094 // Unknown context type - Don't log as an error yet. Let the | 1090 // Unknown context type - Don't log as an error yet. Let the |
1095 // caller work that out. | 1091 // caller work that out. |
1096 BPLOG(INFO) << "MinidumpContext unknown context type " << | 1092 BPLOG(INFO) << "MinidumpContext unknown context type " << |
1097 HexString(cpu_type); | 1093 HexString(cpu_type); |
1098 return false; | 1094 return false; |
1099 break; | 1095 break; |
1100 } | 1096 } |
1101 } | 1097 } |
1102 context_flags_ = context_flags; | 1098 SetContextFlags(context_flags); |
1103 } | 1099 } |
1104 | 1100 |
1105 valid_ = true; | 1101 valid_ = true; |
1106 return true; | 1102 return true; |
1107 } | 1103 } |
1108 | |
1109 | |
1110 uint32_t MinidumpContext::GetContextCPU() const { | |
1111 if (!valid_) { | |
1112 // Don't log a message, GetContextCPU can be legitimately called with | |
1113 // valid_ false by FreeContext, which is called by Read. | |
1114 return 0; | |
1115 } | |
1116 | |
1117 return context_flags_ & MD_CONTEXT_CPU_MASK; | |
1118 } | |
1119 | |
1120 bool MinidumpContext::GetInstructionPointer(uint64_t* ip) const { | |
1121 BPLOG_IF(ERROR, !ip) << "MinidumpContext::GetInstructionPointer " | |
1122 "requires |ip|"; | |
1123 assert(ip); | |
1124 *ip = 0; | |
1125 | |
1126 if (!valid_) { | |
1127 BPLOG(ERROR) << "Invalid MinidumpContext for GetInstructionPointer"; | |
1128 return false; | |
1129 } | |
1130 | |
1131 switch (context_flags_ & MD_CONTEXT_CPU_MASK) { | |
1132 case MD_CONTEXT_AMD64: | |
1133 *ip = context_.amd64->rip; | |
1134 break; | |
1135 case MD_CONTEXT_ARM: | |
1136 *ip = context_.arm->iregs[MD_CONTEXT_ARM_REG_PC]; | |
1137 break; | |
1138 case MD_CONTEXT_ARM64: | |
1139 *ip = context_.arm64->iregs[MD_CONTEXT_ARM64_REG_PC]; | |
1140 break; | |
1141 case MD_CONTEXT_PPC: | |
1142 *ip = context_.ppc->srr0; | |
1143 break; | |
1144 case MD_CONTEXT_PPC64: | |
1145 *ip = context_.ppc64->srr0; | |
1146 break; | |
1147 case MD_CONTEXT_SPARC: | |
1148 *ip = context_.ctx_sparc->pc; | |
1149 break; | |
1150 case MD_CONTEXT_X86: | |
1151 *ip = context_.x86->eip; | |
1152 break; | |
1153 case MD_CONTEXT_MIPS: | |
1154 *ip = context_.ctx_mips->epc; | |
1155 break; | |
1156 default: | |
1157 // This should never happen. | |
1158 BPLOG(ERROR) << "Unknown CPU architecture in GetInstructionPointer"; | |
1159 return false; | |
1160 } | |
1161 return true; | |
1162 } | |
1163 | |
1164 | |
1165 const MDRawContextX86* MinidumpContext::GetContextX86() const { | |
1166 if (GetContextCPU() != MD_CONTEXT_X86) { | |
1167 BPLOG(ERROR) << "MinidumpContext cannot get x86 context"; | |
1168 return NULL; | |
1169 } | |
1170 | |
1171 return context_.x86; | |
1172 } | |
1173 | |
1174 | |
1175 const MDRawContextPPC* MinidumpContext::GetContextPPC() const { | |
1176 if (GetContextCPU() != MD_CONTEXT_PPC) { | |
1177 BPLOG(ERROR) << "MinidumpContext cannot get ppc context"; | |
1178 return NULL; | |
1179 } | |
1180 | |
1181 return context_.ppc; | |
1182 } | |
1183 | |
1184 const MDRawContextPPC64* MinidumpContext::GetContextPPC64() const { | |
1185 if (GetContextCPU() != MD_CONTEXT_PPC64) { | |
1186 BPLOG(ERROR) << "MinidumpContext cannot get ppc64 context"; | |
1187 return NULL; | |
1188 } | |
1189 | |
1190 return context_.ppc64; | |
1191 } | |
1192 | |
1193 const MDRawContextAMD64* MinidumpContext::GetContextAMD64() const { | |
1194 if (GetContextCPU() != MD_CONTEXT_AMD64) { | |
1195 BPLOG(ERROR) << "MinidumpContext cannot get amd64 context"; | |
1196 return NULL; | |
1197 } | |
1198 | |
1199 return context_.amd64; | |
1200 } | |
1201 | |
1202 const MDRawContextSPARC* MinidumpContext::GetContextSPARC() const { | |
1203 if (GetContextCPU() != MD_CONTEXT_SPARC) { | |
1204 BPLOG(ERROR) << "MinidumpContext cannot get sparc context"; | |
1205 return NULL; | |
1206 } | |
1207 | |
1208 return context_.ctx_sparc; | |
1209 } | |
1210 | |
1211 const MDRawContextARM* MinidumpContext::GetContextARM() const { | |
1212 if (GetContextCPU() != MD_CONTEXT_ARM) { | |
1213 BPLOG(ERROR) << "MinidumpContext cannot get arm context"; | |
1214 return NULL; | |
1215 } | |
1216 | |
1217 return context_.arm; | |
1218 } | |
1219 | |
1220 const MDRawContextARM64* MinidumpContext::GetContextARM64() const { | |
1221 if (GetContextCPU() != MD_CONTEXT_ARM64) { | |
1222 BPLOG(ERROR) << "MinidumpContext cannot get arm64 context"; | |
1223 return NULL; | |
1224 } | |
1225 | |
1226 return context_.arm64; | |
1227 } | |
1228 | |
1229 const MDRawContextMIPS* MinidumpContext::GetContextMIPS() const { | |
1230 if (GetContextCPU() != MD_CONTEXT_MIPS) { | |
1231 BPLOG(ERROR) << "MinidumpContext cannot get MIPS context"; | |
1232 return NULL; | |
1233 } | |
1234 | |
1235 return context_.ctx_mips; | |
1236 } | |
1237 | |
1238 void MinidumpContext::FreeContext() { | |
1239 switch (GetContextCPU()) { | |
1240 case MD_CONTEXT_X86: | |
1241 delete context_.x86; | |
1242 break; | |
1243 | |
1244 case MD_CONTEXT_PPC: | |
1245 delete context_.ppc; | |
1246 break; | |
1247 | |
1248 case MD_CONTEXT_PPC64: | |
1249 delete context_.ppc64; | |
1250 break; | |
1251 | |
1252 case MD_CONTEXT_AMD64: | |
1253 delete context_.amd64; | |
1254 break; | |
1255 | |
1256 case MD_CONTEXT_SPARC: | |
1257 delete context_.ctx_sparc; | |
1258 break; | |
1259 | |
1260 case MD_CONTEXT_ARM: | |
1261 delete context_.arm; | |
1262 break; | |
1263 | |
1264 case MD_CONTEXT_ARM64: | |
1265 delete context_.arm64; | |
1266 break; | |
1267 | |
1268 case MD_CONTEXT_MIPS: | |
1269 delete context_.ctx_mips; | |
1270 break; | |
1271 | |
1272 default: | |
1273 // There is no context record (valid_ is false) or there's a | |
1274 // context record for an unknown CPU (shouldn't happen, only known | |
1275 // records are stored by Read). | |
1276 break; | |
1277 } | |
1278 | |
1279 context_flags_ = 0; | |
1280 context_.base = NULL; | |
1281 } | |
1282 | |
1283 | 1104 |
1284 bool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) { | 1105 bool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) { |
1285 // It's OK if the minidump doesn't contain an MD_SYSTEM_INFO_STREAM, | 1106 // It's OK if the minidump doesn't contain an MD_SYSTEM_INFO_STREAM, |
1286 // as this function just implements a sanity check. | 1107 // as this function just implements a sanity check. |
1287 MinidumpSystemInfo* system_info = minidump_->GetSystemInfo(); | 1108 MinidumpSystemInfo* system_info = minidump_->GetSystemInfo(); |
1288 if (!system_info) { | 1109 if (!system_info) { |
1289 BPLOG(INFO) << "MinidumpContext could not be compared against " | 1110 BPLOG(INFO) << "MinidumpContext could not be compared against " |
1290 "MinidumpSystemInfo"; | 1111 "MinidumpSystemInfo"; |
1291 return true; | 1112 return true; |
1292 } | 1113 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 | 1173 |
1353 BPLOG_IF(ERROR, !return_value) << "MinidumpContext CPU " << | 1174 BPLOG_IF(ERROR, !return_value) << "MinidumpContext CPU " << |
1354 HexString(context_cpu_type) << | 1175 HexString(context_cpu_type) << |
1355 " wrong for MinidumpSystemInfo CPU " << | 1176 " wrong for MinidumpSystemInfo CPU " << |
1356 HexString(system_info_cpu_type); | 1177 HexString(system_info_cpu_type); |
1357 | 1178 |
1358 return return_value; | 1179 return return_value; |
1359 } | 1180 } |
1360 | 1181 |
1361 | 1182 |
1362 void MinidumpContext::Print() { | |
1363 if (!valid_) { | |
1364 BPLOG(ERROR) << "MinidumpContext cannot print invalid data"; | |
1365 return; | |
1366 } | |
1367 | |
1368 switch (GetContextCPU()) { | |
1369 case MD_CONTEXT_X86: { | |
1370 const MDRawContextX86* context_x86 = GetContextX86(); | |
1371 printf("MDRawContextX86\n"); | |
1372 printf(" context_flags = 0x%x\n", | |
1373 context_x86->context_flags); | |
1374 printf(" dr0 = 0x%x\n", context_x86->dr0); | |
1375 printf(" dr1 = 0x%x\n", context_x86->dr1); | |
1376 printf(" dr2 = 0x%x\n", context_x86->dr2); | |
1377 printf(" dr3 = 0x%x\n", context_x86->dr3); | |
1378 printf(" dr6 = 0x%x\n", context_x86->dr6); | |
1379 printf(" dr7 = 0x%x\n", context_x86->dr7); | |
1380 printf(" float_save.control_word = 0x%x\n", | |
1381 context_x86->float_save.control_word); | |
1382 printf(" float_save.status_word = 0x%x\n", | |
1383 context_x86->float_save.status_word); | |
1384 printf(" float_save.tag_word = 0x%x\n", | |
1385 context_x86->float_save.tag_word); | |
1386 printf(" float_save.error_offset = 0x%x\n", | |
1387 context_x86->float_save.error_offset); | |
1388 printf(" float_save.error_selector = 0x%x\n", | |
1389 context_x86->float_save.error_selector); | |
1390 printf(" float_save.data_offset = 0x%x\n", | |
1391 context_x86->float_save.data_offset); | |
1392 printf(" float_save.data_selector = 0x%x\n", | |
1393 context_x86->float_save.data_selector); | |
1394 printf(" float_save.register_area[%2d] = 0x", | |
1395 MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE); | |
1396 for (unsigned int register_index = 0; | |
1397 register_index < MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE; | |
1398 ++register_index) { | |
1399 printf("%02x", context_x86->float_save.register_area[register_index]); | |
1400 } | |
1401 printf("\n"); | |
1402 printf(" float_save.cr0_npx_state = 0x%x\n", | |
1403 context_x86->float_save.cr0_npx_state); | |
1404 printf(" gs = 0x%x\n", context_x86->gs); | |
1405 printf(" fs = 0x%x\n", context_x86->fs); | |
1406 printf(" es = 0x%x\n", context_x86->es); | |
1407 printf(" ds = 0x%x\n", context_x86->ds); | |
1408 printf(" edi = 0x%x\n", context_x86->edi); | |
1409 printf(" esi = 0x%x\n", context_x86->esi); | |
1410 printf(" ebx = 0x%x\n", context_x86->ebx); | |
1411 printf(" edx = 0x%x\n", context_x86->edx); | |
1412 printf(" ecx = 0x%x\n", context_x86->ecx); | |
1413 printf(" eax = 0x%x\n", context_x86->eax); | |
1414 printf(" ebp = 0x%x\n", context_x86->ebp); | |
1415 printf(" eip = 0x%x\n", context_x86->eip); | |
1416 printf(" cs = 0x%x\n", context_x86->cs); | |
1417 printf(" eflags = 0x%x\n", context_x86->eflags); | |
1418 printf(" esp = 0x%x\n", context_x86->esp); | |
1419 printf(" ss = 0x%x\n", context_x86->ss); | |
1420 printf(" extended_registers[%3d] = 0x", | |
1421 MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE); | |
1422 for (unsigned int register_index = 0; | |
1423 register_index < MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE; | |
1424 ++register_index) { | |
1425 printf("%02x", context_x86->extended_registers[register_index]); | |
1426 } | |
1427 printf("\n\n"); | |
1428 | |
1429 break; | |
1430 } | |
1431 | |
1432 case MD_CONTEXT_PPC: { | |
1433 const MDRawContextPPC* context_ppc = GetContextPPC(); | |
1434 printf("MDRawContextPPC\n"); | |
1435 printf(" context_flags = 0x%x\n", | |
1436 context_ppc->context_flags); | |
1437 printf(" srr0 = 0x%x\n", context_ppc->srr0); | |
1438 printf(" srr1 = 0x%x\n", context_ppc->srr1); | |
1439 for (unsigned int gpr_index = 0; | |
1440 gpr_index < MD_CONTEXT_PPC_GPR_COUNT; | |
1441 ++gpr_index) { | |
1442 printf(" gpr[%2d] = 0x%x\n", | |
1443 gpr_index, context_ppc->gpr[gpr_index]); | |
1444 } | |
1445 printf(" cr = 0x%x\n", context_ppc->cr); | |
1446 printf(" xer = 0x%x\n", context_ppc->xer); | |
1447 printf(" lr = 0x%x\n", context_ppc->lr); | |
1448 printf(" ctr = 0x%x\n", context_ppc->ctr); | |
1449 printf(" mq = 0x%x\n", context_ppc->mq); | |
1450 printf(" vrsave = 0x%x\n", context_ppc->vrsave); | |
1451 for (unsigned int fpr_index = 0; | |
1452 fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; | |
1453 ++fpr_index) { | |
1454 printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n", | |
1455 fpr_index, context_ppc->float_save.fpregs[fpr_index]); | |
1456 } | |
1457 printf(" float_save.fpscr = 0x%x\n", | |
1458 context_ppc->float_save.fpscr); | |
1459 // TODO(mmentovai): print the 128-bit quantities in | |
1460 // context_ppc->vector_save. This isn't done yet because printf | |
1461 // doesn't support 128-bit quantities, and printing them using | |
1462 // PRIx64 as two 64-bit quantities requires knowledge of the CPU's | |
1463 // byte ordering. | |
1464 printf(" vector_save.save_vrvalid = 0x%x\n", | |
1465 context_ppc->vector_save.save_vrvalid); | |
1466 printf("\n"); | |
1467 | |
1468 break; | |
1469 } | |
1470 | |
1471 case MD_CONTEXT_PPC64: { | |
1472 const MDRawContextPPC64* context_ppc64 = GetContextPPC64(); | |
1473 printf("MDRawContextPPC64\n"); | |
1474 printf(" context_flags = 0x%" PRIx64 "\n", | |
1475 context_ppc64->context_flags); | |
1476 printf(" srr0 = 0x%" PRIx64 "\n", | |
1477 context_ppc64->srr0); | |
1478 printf(" srr1 = 0x%" PRIx64 "\n", | |
1479 context_ppc64->srr1); | |
1480 for (unsigned int gpr_index = 0; | |
1481 gpr_index < MD_CONTEXT_PPC64_GPR_COUNT; | |
1482 ++gpr_index) { | |
1483 printf(" gpr[%2d] = 0x%" PRIx64 "\n", | |
1484 gpr_index, context_ppc64->gpr[gpr_index]); | |
1485 } | |
1486 printf(" cr = 0x%" PRIx64 "\n", context_ppc64->cr); | |
1487 printf(" xer = 0x%" PRIx64 "\n", | |
1488 context_ppc64->xer); | |
1489 printf(" lr = 0x%" PRIx64 "\n", context_ppc64->lr); | |
1490 printf(" ctr = 0x%" PRIx64 "\n", | |
1491 context_ppc64->ctr); | |
1492 printf(" vrsave = 0x%" PRIx64 "\n", | |
1493 context_ppc64->vrsave); | |
1494 for (unsigned int fpr_index = 0; | |
1495 fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT; | |
1496 ++fpr_index) { | |
1497 printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n", | |
1498 fpr_index, context_ppc64->float_save.fpregs[fpr_index]); | |
1499 } | |
1500 printf(" float_save.fpscr = 0x%x\n", | |
1501 context_ppc64->float_save.fpscr); | |
1502 // TODO(mmentovai): print the 128-bit quantities in | |
1503 // context_ppc64->vector_save. This isn't done yet because printf | |
1504 // doesn't support 128-bit quantities, and printing them using | |
1505 // PRIx64 as two 64-bit quantities requires knowledge of the CPU's | |
1506 // byte ordering. | |
1507 printf(" vector_save.save_vrvalid = 0x%x\n", | |
1508 context_ppc64->vector_save.save_vrvalid); | |
1509 printf("\n"); | |
1510 | |
1511 break; | |
1512 } | |
1513 | |
1514 case MD_CONTEXT_AMD64: { | |
1515 const MDRawContextAMD64* context_amd64 = GetContextAMD64(); | |
1516 printf("MDRawContextAMD64\n"); | |
1517 printf(" p1_home = 0x%" PRIx64 "\n", | |
1518 context_amd64->p1_home); | |
1519 printf(" p2_home = 0x%" PRIx64 "\n", | |
1520 context_amd64->p2_home); | |
1521 printf(" p3_home = 0x%" PRIx64 "\n", | |
1522 context_amd64->p3_home); | |
1523 printf(" p4_home = 0x%" PRIx64 "\n", | |
1524 context_amd64->p4_home); | |
1525 printf(" p5_home = 0x%" PRIx64 "\n", | |
1526 context_amd64->p5_home); | |
1527 printf(" p6_home = 0x%" PRIx64 "\n", | |
1528 context_amd64->p6_home); | |
1529 printf(" context_flags = 0x%x\n", | |
1530 context_amd64->context_flags); | |
1531 printf(" mx_csr = 0x%x\n", | |
1532 context_amd64->mx_csr); | |
1533 printf(" cs = 0x%x\n", context_amd64->cs); | |
1534 printf(" ds = 0x%x\n", context_amd64->ds); | |
1535 printf(" es = 0x%x\n", context_amd64->es); | |
1536 printf(" fs = 0x%x\n", context_amd64->fs); | |
1537 printf(" gs = 0x%x\n", context_amd64->gs); | |
1538 printf(" ss = 0x%x\n", context_amd64->ss); | |
1539 printf(" eflags = 0x%x\n", context_amd64->eflags); | |
1540 printf(" dr0 = 0x%" PRIx64 "\n", context_amd64->dr0); | |
1541 printf(" dr1 = 0x%" PRIx64 "\n", context_amd64->dr1); | |
1542 printf(" dr2 = 0x%" PRIx64 "\n", context_amd64->dr2); | |
1543 printf(" dr3 = 0x%" PRIx64 "\n", context_amd64->dr3); | |
1544 printf(" dr6 = 0x%" PRIx64 "\n", context_amd64->dr6); | |
1545 printf(" dr7 = 0x%" PRIx64 "\n", context_amd64->dr7); | |
1546 printf(" rax = 0x%" PRIx64 "\n", context_amd64->rax); | |
1547 printf(" rcx = 0x%" PRIx64 "\n", context_amd64->rcx); | |
1548 printf(" rdx = 0x%" PRIx64 "\n", context_amd64->rdx); | |
1549 printf(" rbx = 0x%" PRIx64 "\n", context_amd64->rbx); | |
1550 printf(" rsp = 0x%" PRIx64 "\n", context_amd64->rsp); | |
1551 printf(" rbp = 0x%" PRIx64 "\n", context_amd64->rbp); | |
1552 printf(" rsi = 0x%" PRIx64 "\n", context_amd64->rsi); | |
1553 printf(" rdi = 0x%" PRIx64 "\n", context_amd64->rdi); | |
1554 printf(" r8 = 0x%" PRIx64 "\n", context_amd64->r8); | |
1555 printf(" r9 = 0x%" PRIx64 "\n", context_amd64->r9); | |
1556 printf(" r10 = 0x%" PRIx64 "\n", context_amd64->r10); | |
1557 printf(" r11 = 0x%" PRIx64 "\n", context_amd64->r11); | |
1558 printf(" r12 = 0x%" PRIx64 "\n", context_amd64->r12); | |
1559 printf(" r13 = 0x%" PRIx64 "\n", context_amd64->r13); | |
1560 printf(" r14 = 0x%" PRIx64 "\n", context_amd64->r14); | |
1561 printf(" r15 = 0x%" PRIx64 "\n", context_amd64->r15); | |
1562 printf(" rip = 0x%" PRIx64 "\n", context_amd64->rip); | |
1563 // TODO: print xmm, vector, debug registers | |
1564 printf("\n"); | |
1565 break; | |
1566 } | |
1567 | |
1568 case MD_CONTEXT_SPARC: { | |
1569 const MDRawContextSPARC* context_sparc = GetContextSPARC(); | |
1570 printf("MDRawContextSPARC\n"); | |
1571 printf(" context_flags = 0x%x\n", | |
1572 context_sparc->context_flags); | |
1573 for (unsigned int g_r_index = 0; | |
1574 g_r_index < MD_CONTEXT_SPARC_GPR_COUNT; | |
1575 ++g_r_index) { | |
1576 printf(" g_r[%2d] = 0x%" PRIx64 "\n", | |
1577 g_r_index, context_sparc->g_r[g_r_index]); | |
1578 } | |
1579 printf(" ccr = 0x%" PRIx64 "\n", context_sparc->ccr); | |
1580 printf(" pc = 0x%" PRIx64 "\n", context_sparc->pc); | |
1581 printf(" npc = 0x%" PRIx64 "\n", context_sparc->npc); | |
1582 printf(" y = 0x%" PRIx64 "\n", context_sparc->y); | |
1583 printf(" asi = 0x%" PRIx64 "\n", context_sparc->asi); | |
1584 printf(" fprs = 0x%" PRIx64 "\n", context_sparc->fprs); | |
1585 | |
1586 for (unsigned int fpr_index = 0; | |
1587 fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT; | |
1588 ++fpr_index) { | |
1589 printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", | |
1590 fpr_index, context_sparc->float_save.regs[fpr_index]); | |
1591 } | |
1592 printf(" float_save.filler = 0x%" PRIx64 "\n", | |
1593 context_sparc->float_save.filler); | |
1594 printf(" float_save.fsr = 0x%" PRIx64 "\n", | |
1595 context_sparc->float_save.fsr); | |
1596 break; | |
1597 } | |
1598 | |
1599 case MD_CONTEXT_ARM: { | |
1600 const MDRawContextARM* context_arm = GetContextARM(); | |
1601 printf("MDRawContextARM\n"); | |
1602 printf(" context_flags = 0x%x\n", | |
1603 context_arm->context_flags); | |
1604 for (unsigned int ireg_index = 0; | |
1605 ireg_index < MD_CONTEXT_ARM_GPR_COUNT; | |
1606 ++ireg_index) { | |
1607 printf(" iregs[%2d] = 0x%x\n", | |
1608 ireg_index, context_arm->iregs[ireg_index]); | |
1609 } | |
1610 printf(" cpsr = 0x%x\n", context_arm->cpsr); | |
1611 printf(" float_save.fpscr = 0x%" PRIx64 "\n", | |
1612 context_arm->float_save.fpscr); | |
1613 for (unsigned int fpr_index = 0; | |
1614 fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; | |
1615 ++fpr_index) { | |
1616 printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", | |
1617 fpr_index, context_arm->float_save.regs[fpr_index]); | |
1618 } | |
1619 for (unsigned int fpe_index = 0; | |
1620 fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; | |
1621 ++fpe_index) { | |
1622 printf(" float_save.extra[%2d] = 0x%" PRIx32 "\n", | |
1623 fpe_index, context_arm->float_save.extra[fpe_index]); | |
1624 } | |
1625 | |
1626 break; | |
1627 } | |
1628 | |
1629 case MD_CONTEXT_ARM64: { | |
1630 const MDRawContextARM64* context_arm64 = GetContextARM64(); | |
1631 printf("MDRawContextARM64\n"); | |
1632 printf(" context_flags = 0x%" PRIx64 "\n", | |
1633 context_arm64->context_flags); | |
1634 for (unsigned int ireg_index = 0; | |
1635 ireg_index < MD_CONTEXT_ARM64_GPR_COUNT; | |
1636 ++ireg_index) { | |
1637 printf(" iregs[%2d] = 0x%" PRIx64 "\n", | |
1638 ireg_index, context_arm64->iregs[ireg_index]); | |
1639 } | |
1640 printf(" cpsr = 0x%x\n", context_arm64->cpsr); | |
1641 printf(" float_save.fpsr = 0x%x\n", context_arm64->float_save.fpsr); | |
1642 printf(" float_save.fpcr = 0x%x\n", context_arm64->float_save.fpcr); | |
1643 | |
1644 for (unsigned int freg_index = 0; | |
1645 freg_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT; | |
1646 ++freg_index) { | |
1647 uint128_struct fp_value = context_arm64->float_save.regs[freg_index]; | |
1648 printf(" float_save.regs[%2d] = 0x%" PRIx64 "%" PRIx64 "\n", | |
1649 freg_index, fp_value.high, fp_value.low); | |
1650 } | |
1651 break; | |
1652 } | |
1653 | |
1654 case MD_CONTEXT_MIPS: { | |
1655 const MDRawContextMIPS* context_mips = GetContextMIPS(); | |
1656 printf("MDRawContextMIPS\n"); | |
1657 printf(" context_flags = 0x%x\n", | |
1658 context_mips->context_flags); | |
1659 for (int ireg_index = 0; | |
1660 ireg_index < MD_CONTEXT_MIPS_GPR_COUNT; | |
1661 ++ireg_index) { | |
1662 printf(" iregs[%2d] = 0x%" PRIx64 "\n", | |
1663 ireg_index, context_mips->iregs[ireg_index]); | |
1664 } | |
1665 printf(" mdhi = 0x%" PRIx64 "\n", | |
1666 context_mips->mdhi); | |
1667 printf(" mdlo = 0x%" PRIx64 "\n", | |
1668 context_mips->mdhi); | |
1669 for (int dsp_index = 0; | |
1670 dsp_index < MD_CONTEXT_MIPS_DSP_COUNT; | |
1671 ++dsp_index) { | |
1672 printf(" hi[%1d] = 0x%" PRIx32 "\n", | |
1673 dsp_index, context_mips->hi[dsp_index]); | |
1674 printf(" lo[%1d] = 0x%" PRIx32 "\n", | |
1675 dsp_index, context_mips->lo[dsp_index]); | |
1676 } | |
1677 printf(" dsp_control = 0x%" PRIx32 "\n", | |
1678 context_mips->dsp_control); | |
1679 printf(" epc = 0x%" PRIx64 "\n", | |
1680 context_mips->epc); | |
1681 printf(" badvaddr = 0x%" PRIx64 "\n", | |
1682 context_mips->badvaddr); | |
1683 printf(" status = 0x%" PRIx32 "\n", | |
1684 context_mips->status); | |
1685 printf(" cause = 0x%" PRIx32 "\n", | |
1686 context_mips->cause); | |
1687 | |
1688 for (int fpr_index = 0; | |
1689 fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; | |
1690 ++fpr_index) { | |
1691 printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", | |
1692 fpr_index, context_mips->float_save.regs[fpr_index]); | |
1693 } | |
1694 printf(" float_save.fpcsr = 0x%" PRIx32 "\n", | |
1695 context_mips->float_save.fpcsr); | |
1696 printf(" float_save.fir = 0x%" PRIx32 "\n", | |
1697 context_mips->float_save.fir); | |
1698 break; | |
1699 } | |
1700 | |
1701 default: { | |
1702 break; | |
1703 } | |
1704 } | |
1705 } | |
1706 | |
1707 | |
1708 // | 1183 // |
1709 // MinidumpMemoryRegion | 1184 // MinidumpMemoryRegion |
1710 // | 1185 // |
1711 | 1186 |
1712 | 1187 |
1713 uint32_t MinidumpMemoryRegion::max_bytes_ = 1024 * 1024; // 1MB | 1188 uint32_t MinidumpMemoryRegion::max_bytes_ = 1024 * 1024; // 1MB |
1714 | 1189 |
1715 | 1190 |
1716 MinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump) | 1191 MinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump) |
1717 : MinidumpObject(minidump), | 1192 : MinidumpObject(minidump), |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 return GetMemoryAtAddressInternal(address, value); | 1335 return GetMemoryAtAddressInternal(address, value); |
1861 } | 1336 } |
1862 | 1337 |
1863 | 1338 |
1864 bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, | 1339 bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t address, |
1865 uint64_t* value) const { | 1340 uint64_t* value) const { |
1866 return GetMemoryAtAddressInternal(address, value); | 1341 return GetMemoryAtAddressInternal(address, value); |
1867 } | 1342 } |
1868 | 1343 |
1869 | 1344 |
1870 void MinidumpMemoryRegion::Print() { | 1345 void MinidumpMemoryRegion::Print() const { |
1871 if (!valid_) { | 1346 if (!valid_) { |
1872 BPLOG(ERROR) << "MinidumpMemoryRegion cannot print invalid data"; | 1347 BPLOG(ERROR) << "MinidumpMemoryRegion cannot print invalid data"; |
1873 return; | 1348 return; |
1874 } | 1349 } |
1875 | 1350 |
1876 const uint8_t* memory = GetMemory(); | 1351 const uint8_t* memory = GetMemory(); |
1877 if (memory) { | 1352 if (memory) { |
1878 printf("0x"); | 1353 printf("0x"); |
1879 for (unsigned int byte_index = 0; | 1354 for (unsigned int byte_index = 0; |
1880 byte_index < descriptor_->memory.data_size; | 1355 byte_index < descriptor_->memory.data_size; |
(...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3065 uint64_t base_address = module->base_address(); | 2540 uint64_t base_address = module->base_address(); |
3066 uint64_t module_size = module->size(); | 2541 uint64_t module_size = module->size(); |
3067 if (base_address == static_cast<uint64_t>(-1)) { | 2542 if (base_address == static_cast<uint64_t>(-1)) { |
3068 BPLOG(ERROR) << "MinidumpModuleList found bad base address " | 2543 BPLOG(ERROR) << "MinidumpModuleList found bad base address " |
3069 "for module " << module_index << "/" << module_count << | 2544 "for module " << module_index << "/" << module_count << |
3070 ", " << module->code_file(); | 2545 ", " << module->code_file(); |
3071 return false; | 2546 return false; |
3072 } | 2547 } |
3073 | 2548 |
3074 if (!range_map_->StoreRange(base_address, module_size, module_index)) { | 2549 if (!range_map_->StoreRange(base_address, module_size, module_index)) { |
3075 BPLOG(ERROR) << "MinidumpModuleList could not store module " << | 2550 // Android's shared memory implementation /dev/ashmem can contain |
3076 module_index << "/" << module_count << ", " << | 2551 // duplicate entries for JITted code, so ignore these. |
3077 module->code_file() << ", " << | 2552 // TODO(wfh): Remove this code when Android is fixed. |
3078 HexString(base_address) << "+" << | 2553 // See https://crbug.com/439531 |
3079 HexString(module_size); | 2554 const string kDevAshmem("/dev/ashmem/"); |
3080 return false; | 2555 if (module->code_file().compare( |
| 2556 0, kDevAshmem.length(), kDevAshmem) != 0) { |
| 2557 BPLOG(ERROR) << "MinidumpModuleList could not store module " << |
| 2558 module_index << "/" << module_count << ", " << |
| 2559 module->code_file() << ", " << |
| 2560 HexString(base_address) << "+" << |
| 2561 HexString(module_size); |
| 2562 return false; |
| 2563 } else { |
| 2564 BPLOG(INFO) << "MinidumpModuleList ignoring overlapping module " << |
| 2565 module_index << "/" << module_count << ", " << |
| 2566 module->code_file() << ", " << |
| 2567 HexString(base_address) << "+" << |
| 2568 HexString(module_size); |
| 2569 } |
3081 } | 2570 } |
3082 } | 2571 } |
3083 | 2572 |
3084 modules_ = modules.release(); | 2573 modules_ = modules.release(); |
3085 } | 2574 } |
3086 | 2575 |
3087 module_count_ = module_count; | 2576 module_count_ = module_count; |
3088 | 2577 |
3089 valid_ = true; | 2578 valid_ = true; |
3090 return true; | 2579 return true; |
(...skipping 2042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5133 return NULL; | 4622 return NULL; |
5134 } | 4623 } |
5135 | 4624 |
5136 *stream = new_stream.release(); | 4625 *stream = new_stream.release(); |
5137 info->stream = *stream; | 4626 info->stream = *stream; |
5138 return *stream; | 4627 return *stream; |
5139 } | 4628 } |
5140 | 4629 |
5141 | 4630 |
5142 } // namespace google_breakpad | 4631 } // namespace google_breakpad |
LEFT | RIGHT |