| OLD | NEW |
| 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 21 matching lines...) Expand all Loading... |
| 32 // Implement the DwarfCUToModule class; see dwarf_cu_to_module.h. | 32 // Implement the DwarfCUToModule class; see dwarf_cu_to_module.h. |
| 33 | 33 |
| 34 // For <inttypes.h> PRI* macros, before anything else might #include it. | 34 // For <inttypes.h> PRI* macros, before anything else might #include it. |
| 35 #ifndef __STDC_FORMAT_MACROS | 35 #ifndef __STDC_FORMAT_MACROS |
| 36 #define __STDC_FORMAT_MACROS | 36 #define __STDC_FORMAT_MACROS |
| 37 #endif /* __STDC_FORMAT_MACROS */ | 37 #endif /* __STDC_FORMAT_MACROS */ |
| 38 | 38 |
| 39 #include "common/dwarf_cu_to_module.h" | 39 #include "common/dwarf_cu_to_module.h" |
| 40 | 40 |
| 41 #include <assert.h> | 41 #include <assert.h> |
| 42 #if !defined(__ANDROID__) | |
| 43 #include <cxxabi.h> | |
| 44 #endif | |
| 45 #include <inttypes.h> | 42 #include <inttypes.h> |
| 46 #include <stdint.h> | 43 #include <stdint.h> |
| 47 #include <stdio.h> | 44 #include <stdio.h> |
| 48 | 45 |
| 49 #include <algorithm> | 46 #include <algorithm> |
| 50 #include <utility> | 47 #include <utility> |
| 51 | 48 |
| 52 #include "common/dwarf_line_to_module.h" | 49 #include "common/dwarf_line_to_module.h" |
| 53 #include "common/unordered.h" | 50 #include "common/unordered.h" |
| 54 | 51 |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 } | 340 } |
| 344 | 341 |
| 345 void DwarfCUToModule::GenericDIEHandler::ProcessAttributeString( | 342 void DwarfCUToModule::GenericDIEHandler::ProcessAttributeString( |
| 346 enum DwarfAttribute attr, | 343 enum DwarfAttribute attr, |
| 347 enum DwarfForm form, | 344 enum DwarfForm form, |
| 348 const string &data) { | 345 const string &data) { |
| 349 switch (attr) { | 346 switch (attr) { |
| 350 case dwarf2reader::DW_AT_name: | 347 case dwarf2reader::DW_AT_name: |
| 351 name_attribute_ = AddStringToPool(data); | 348 name_attribute_ = AddStringToPool(data); |
| 352 break; | 349 break; |
| 353 case dwarf2reader::DW_AT_MIPS_linkage_name: { | 350 case dwarf2reader::DW_AT_MIPS_linkage_name: |
| 354 char* demangled = NULL; | 351 case dwarf2reader::DW_AT_linkage_name: { |
| 355 int status = -1; | 352 string demangled; |
| 356 #if !defined(__ANDROID__) // Android NDK doesn't provide abi::__cxa_demangle. | 353 Language::DemangleResult result = |
| 357 demangled = abi::__cxa_demangle(data.c_str(), NULL, NULL, &status); | 354 cu_context_->language->DemangleName(data, &demangled); |
| 358 #endif | 355 switch (result) { |
| 359 if (status != 0) { | 356 case Language::kDemangleSuccess: |
| 360 cu_context_->reporter->DemangleError(data, status); | 357 demangled_name_ = AddStringToPool(demangled); |
| 361 demangled_name_ = ""; | 358 break; |
| 362 break; | 359 |
| 363 } | 360 case Language::kDemangleFailure: |
| 364 if (demangled) { | 361 cu_context_->reporter->DemangleError(data); |
| 365 demangled_name_ = AddStringToPool(demangled); | 362 // fallthrough |
| 366 free(reinterpret_cast<void*>(demangled)); | 363 case Language::kDontDemangle: |
| 364 demangled_name_.clear(); |
| 365 break; |
| 367 } | 366 } |
| 368 break; | 367 break; |
| 369 } | 368 } |
| 370 default: break; | 369 default: break; |
| 371 } | 370 } |
| 372 } | 371 } |
| 373 | 372 |
| 374 string DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() { | 373 string DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() { |
| 375 // Use the demangled name, if one is available. Demangled names are | 374 // Use the demangled name, if one is available. Demangled names are |
| 376 // preferable to those inferred from the DWARF structure because they | 375 // preferable to those inferred from the DWARF structure because they |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 (line.size == 0 ? " (zero-length)" : ""), | 668 (line.size == 0 ? " (zero-length)" : ""), |
| 670 line.file->name.c_str(), line.number, line.address); | 669 line.file->name.c_str(), line.number, line.address); |
| 671 } | 670 } |
| 672 | 671 |
| 673 void DwarfCUToModule::WarningReporter::UnnamedFunction(uint64 offset) { | 672 void DwarfCUToModule::WarningReporter::UnnamedFunction(uint64 offset) { |
| 674 CUHeading(); | 673 CUHeading(); |
| 675 fprintf(stderr, "%s: warning: function at offset 0x%llx has no name\n", | 674 fprintf(stderr, "%s: warning: function at offset 0x%llx has no name\n", |
| 676 filename_.c_str(), offset); | 675 filename_.c_str(), offset); |
| 677 } | 676 } |
| 678 | 677 |
| 679 void DwarfCUToModule::WarningReporter::DemangleError( | 678 void DwarfCUToModule::WarningReporter::DemangleError(const string &input) { |
| 680 const string &input, int error) { | |
| 681 CUHeading(); | 679 CUHeading(); |
| 682 fprintf(stderr, "%s: warning: failed to demangle %s with error %d\n", | 680 fprintf(stderr, "%s: warning: failed to demangle %s\n", |
| 683 filename_.c_str(), input.c_str(), error); | 681 filename_.c_str(), input.c_str()); |
| 684 } | 682 } |
| 685 | 683 |
| 686 void DwarfCUToModule::WarningReporter::UnhandledInterCUReference( | 684 void DwarfCUToModule::WarningReporter::UnhandledInterCUReference( |
| 687 uint64 offset, uint64 target) { | 685 uint64 offset, uint64 target) { |
| 688 CUHeading(); | 686 CUHeading(); |
| 689 fprintf(stderr, "%s: warning: the DIE at offset 0x%llx has a " | 687 fprintf(stderr, "%s: warning: the DIE at offset 0x%llx has a " |
| 690 "DW_FORM_ref_addr attribute with an inter-CU reference to " | 688 "DW_FORM_ref_addr attribute with an inter-CU reference to " |
| 691 "0x%llx, but inter-CU reference handling is turned off.\n", | 689 "0x%llx, but inter-CU reference handling is turned off.\n", |
| 692 filename_.c_str(), offset, target); | 690 filename_.c_str(), offset, target); |
| 693 } | 691 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 dwarf2reader::DIEHandler *DwarfCUToModule::FindChildHandler( | 752 dwarf2reader::DIEHandler *DwarfCUToModule::FindChildHandler( |
| 755 uint64 offset, | 753 uint64 offset, |
| 756 enum DwarfTag tag) { | 754 enum DwarfTag tag) { |
| 757 switch (tag) { | 755 switch (tag) { |
| 758 case dwarf2reader::DW_TAG_subprogram: | 756 case dwarf2reader::DW_TAG_subprogram: |
| 759 return new FuncHandler(cu_context_.get(), child_context_.get(), offset); | 757 return new FuncHandler(cu_context_.get(), child_context_.get(), offset); |
| 760 case dwarf2reader::DW_TAG_namespace: | 758 case dwarf2reader::DW_TAG_namespace: |
| 761 case dwarf2reader::DW_TAG_class_type: | 759 case dwarf2reader::DW_TAG_class_type: |
| 762 case dwarf2reader::DW_TAG_structure_type: | 760 case dwarf2reader::DW_TAG_structure_type: |
| 763 case dwarf2reader::DW_TAG_union_type: | 761 case dwarf2reader::DW_TAG_union_type: |
| 762 case dwarf2reader::DW_TAG_module: |
| 764 return new NamedScopeHandler(cu_context_.get(), child_context_.get(), | 763 return new NamedScopeHandler(cu_context_.get(), child_context_.get(), |
| 765 offset); | 764 offset); |
| 766 default: | 765 default: |
| 767 return NULL; | 766 return NULL; |
| 768 } | 767 } |
| 769 } | 768 } |
| 770 | 769 |
| 771 void DwarfCUToModule::SetLanguage(DwarfLanguage language) { | 770 void DwarfCUToModule::SetLanguage(DwarfLanguage language) { |
| 772 switch (language) { | 771 switch (language) { |
| 773 case dwarf2reader::DW_LANG_Java: | 772 case dwarf2reader::DW_LANG_Java: |
| 774 cu_context_->language = Language::Java; | 773 cu_context_->language = Language::Java; |
| 775 break; | 774 break; |
| 776 | 775 |
| 776 case dwarf2reader::DW_LANG_Swift: |
| 777 cu_context_->language = Language::Swift; |
| 778 break; |
| 779 |
| 777 // DWARF has no generic language code for assembly language; this is | 780 // DWARF has no generic language code for assembly language; this is |
| 778 // what the GNU toolchain uses. | 781 // what the GNU toolchain uses. |
| 779 case dwarf2reader::DW_LANG_Mips_Assembler: | 782 case dwarf2reader::DW_LANG_Mips_Assembler: |
| 780 cu_context_->language = Language::Assembler; | 783 cu_context_->language = Language::Assembler; |
| 781 break; | 784 break; |
| 782 | 785 |
| 783 // C++ covers so many cases that it probably has some way to cope | 786 // C++ covers so many cases that it probably has some way to cope |
| 784 // with whatever the other languages throw at us. So make it the | 787 // with whatever the other languages throw at us. So make it the |
| 785 // default. | 788 // default. |
| 786 // | 789 // |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1066 return dwarf_version >= 2; | 1069 return dwarf_version >= 2; |
| 1067 } | 1070 } |
| 1068 | 1071 |
| 1069 bool DwarfCUToModule::StartRootDIE(uint64 offset, enum DwarfTag tag) { | 1072 bool DwarfCUToModule::StartRootDIE(uint64 offset, enum DwarfTag tag) { |
| 1070 // We don't deal with partial compilation units (the only other tag | 1073 // We don't deal with partial compilation units (the only other tag |
| 1071 // likely to be used for root DIE). | 1074 // likely to be used for root DIE). |
| 1072 return tag == dwarf2reader::DW_TAG_compile_unit; | 1075 return tag == dwarf2reader::DW_TAG_compile_unit; |
| 1073 } | 1076 } |
| 1074 | 1077 |
| 1075 } // namespace google_breakpad | 1078 } // namespace google_breakpad |
| OLD | NEW |