OLD | NEW |
1 // Copyright (c) 2011 Google Inc. | 1 // Copyright (c) 2011 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 #include "common/dwarf/dwarf2diehandler.h" | 57 #include "common/dwarf/dwarf2diehandler.h" |
58 #include "common/dwarf_cfi_to_module.h" | 58 #include "common/dwarf_cfi_to_module.h" |
59 #include "common/dwarf_cu_to_module.h" | 59 #include "common/dwarf_cu_to_module.h" |
60 #include "common/dwarf_line_to_module.h" | 60 #include "common/dwarf_line_to_module.h" |
61 #include "common/linux/crc32.h" | 61 #include "common/linux/crc32.h" |
62 #include "common/linux/eintr_wrapper.h" | 62 #include "common/linux/eintr_wrapper.h" |
63 #include "common/linux/elfutils.h" | 63 #include "common/linux/elfutils.h" |
64 #include "common/linux/elfutils-inl.h" | 64 #include "common/linux/elfutils-inl.h" |
65 #include "common/linux/elf_symbols_to_module.h" | 65 #include "common/linux/elf_symbols_to_module.h" |
66 #include "common/linux/file_id.h" | 66 #include "common/linux/file_id.h" |
| 67 #include "common/memory.h" |
67 #include "common/module.h" | 68 #include "common/module.h" |
68 #include "common/scoped_ptr.h" | 69 #include "common/scoped_ptr.h" |
69 #ifndef NO_STABS_SUPPORT | 70 #ifndef NO_STABS_SUPPORT |
70 #include "common/stabs_reader.h" | 71 #include "common/stabs_reader.h" |
71 #include "common/stabs_to_module.h" | 72 #include "common/stabs_to_module.h" |
72 #endif | 73 #endif |
73 #include "common/using_std_string.h" | 74 #include "common/using_std_string.h" |
74 | 75 |
75 // This namespace contains helper functions. | 76 // This namespace contains helper functions. |
76 namespace { | 77 namespace { |
77 | 78 |
78 using google_breakpad::DumpOptions; | 79 using google_breakpad::DumpOptions; |
79 using google_breakpad::DwarfCFIToModule; | 80 using google_breakpad::DwarfCFIToModule; |
80 using google_breakpad::DwarfCUToModule; | 81 using google_breakpad::DwarfCUToModule; |
81 using google_breakpad::DwarfLineToModule; | 82 using google_breakpad::DwarfLineToModule; |
82 using google_breakpad::ElfClass; | 83 using google_breakpad::ElfClass; |
83 using google_breakpad::ElfClass32; | 84 using google_breakpad::ElfClass32; |
84 using google_breakpad::ElfClass64; | 85 using google_breakpad::ElfClass64; |
| 86 using google_breakpad::FileID; |
85 using google_breakpad::FindElfSectionByName; | 87 using google_breakpad::FindElfSectionByName; |
86 using google_breakpad::GetOffset; | 88 using google_breakpad::GetOffset; |
87 using google_breakpad::IsValidElf; | 89 using google_breakpad::IsValidElf; |
| 90 using google_breakpad::kDefaultBuildIdSize; |
88 using google_breakpad::Module; | 91 using google_breakpad::Module; |
| 92 using google_breakpad::PageAllocator; |
89 #ifndef NO_STABS_SUPPORT | 93 #ifndef NO_STABS_SUPPORT |
90 using google_breakpad::StabsToModule; | 94 using google_breakpad::StabsToModule; |
91 #endif | 95 #endif |
92 using google_breakpad::scoped_ptr; | 96 using google_breakpad::scoped_ptr; |
| 97 using google_breakpad::wasteful_vector; |
93 | 98 |
94 // Define AARCH64 ELF architecture if host machine does not include this define. | 99 // Define AARCH64 ELF architecture if host machine does not include this define. |
95 #ifndef EM_AARCH64 | 100 #ifndef EM_AARCH64 |
96 #define EM_AARCH64 183 | 101 #define EM_AARCH64 183 |
97 #endif | 102 #endif |
98 | 103 |
99 // Define SHT_ANDROID_REL and SHT_ANDROID_RELA if not defined by the host. | 104 // Define SHT_ANDROID_REL and SHT_ANDROID_RELA if not defined by the host. |
100 // Sections with this type contain Android packed relocations. | 105 // Sections with this type contain Android packed relocations. |
101 #ifndef SHT_ANDROID_REL | 106 #ifndef SHT_ANDROID_REL |
102 #define SHT_ANDROID_REL (SHT_LOOS + 1) | 107 #define SHT_ANDROID_REL (SHT_LOOS + 1) |
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 case EM_PPC64: return "ppc64"; | 852 case EM_PPC64: return "ppc64"; |
848 case EM_PPC: return "ppc"; | 853 case EM_PPC: return "ppc"; |
849 case EM_S390: return "s390"; | 854 case EM_S390: return "s390"; |
850 case EM_SPARC: return "sparc"; | 855 case EM_SPARC: return "sparc"; |
851 case EM_SPARCV9: return "sparcv9"; | 856 case EM_SPARCV9: return "sparcv9"; |
852 case EM_X86_64: return "x86_64"; | 857 case EM_X86_64: return "x86_64"; |
853 default: return NULL; | 858 default: return NULL; |
854 } | 859 } |
855 } | 860 } |
856 | 861 |
857 // Format the Elf file identifier in IDENTIFIER as a UUID with the | |
858 // dashes removed. | |
859 string FormatIdentifier(unsigned char identifier[16]) { | |
860 char identifier_str[40]; | |
861 google_breakpad::FileID::ConvertIdentifierToString( | |
862 identifier, | |
863 identifier_str, | |
864 sizeof(identifier_str)); | |
865 string id_no_dash; | |
866 for (int i = 0; identifier_str[i] != '\0'; ++i) | |
867 if (identifier_str[i] != '-') | |
868 id_no_dash += identifier_str[i]; | |
869 // Add an extra "0" by the end. PDB files on Windows have an 'age' | |
870 // number appended to the end of the file identifier; this isn't | |
871 // really used or necessary on other platforms, but be consistent. | |
872 id_no_dash += '0'; | |
873 return id_no_dash; | |
874 } | |
875 | |
876 // Return the non-directory portion of FILENAME: the portion after the | 862 // Return the non-directory portion of FILENAME: the portion after the |
877 // last slash, or the whole filename if there are no slashes. | 863 // last slash, or the whole filename if there are no slashes. |
878 string BaseFileName(const string &filename) { | 864 string BaseFileName(const string &filename) { |
879 // Lots of copies! basename's behavior is less than ideal. | 865 // Lots of copies! basename's behavior is less than ideal. |
880 char* c_filename = strdup(filename.c_str()); | 866 char* c_filename = strdup(filename.c_str()); |
881 string base = basename(c_filename); | 867 string base = basename(c_filename); |
882 free(c_filename); | 868 free(c_filename); |
883 return base; | 869 return base; |
884 } | 870 } |
885 | 871 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 template<typename ElfClass> | 903 template<typename ElfClass> |
918 bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, | 904 bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, |
919 const string& obj_filename, | 905 const string& obj_filename, |
920 const std::vector<string>& debug_dirs, | 906 const std::vector<string>& debug_dirs, |
921 const DumpOptions& options, | 907 const DumpOptions& options, |
922 Module** out_module) { | 908 Module** out_module) { |
923 typedef typename ElfClass::Ehdr Ehdr; | 909 typedef typename ElfClass::Ehdr Ehdr; |
924 | 910 |
925 *out_module = NULL; | 911 *out_module = NULL; |
926 | 912 |
927 unsigned char identifier[16]; | 913 PageAllocator allocator; |
928 if (!google_breakpad::FileID::ElfFileIdentifierFromMappedFile(elf_header, | 914 wasteful_vector<uint8_t> identifier(&allocator, kDefaultBuildIdSize); |
929 identifier)) { | 915 if (!FileID::ElfFileIdentifierFromMappedFile(elf_header, |
| 916 identifier)) { |
930 fprintf(stderr, "%s: unable to generate file identifier\n", | 917 fprintf(stderr, "%s: unable to generate file identifier\n", |
931 obj_filename.c_str()); | 918 obj_filename.c_str()); |
932 return false; | 919 return false; |
933 } | 920 } |
934 | 921 |
935 const char *architecture = ElfArchitecture<ElfClass>(elf_header); | 922 const char *architecture = ElfArchitecture<ElfClass>(elf_header); |
936 if (!architecture) { | 923 if (!architecture) { |
937 fprintf(stderr, "%s: unrecognized ELF machine architecture: %d\n", | 924 fprintf(stderr, "%s: unrecognized ELF machine architecture: %d\n", |
938 obj_filename.c_str(), elf_header->e_machine); | 925 obj_filename.c_str(), elf_header->e_machine); |
939 return false; | 926 return false; |
940 } | 927 } |
941 | 928 |
942 // Figure out what endianness this file is. | 929 // Figure out what endianness this file is. |
943 bool big_endian; | 930 bool big_endian; |
944 if (!ElfEndianness<ElfClass>(elf_header, &big_endian)) | 931 if (!ElfEndianness<ElfClass>(elf_header, &big_endian)) |
945 return false; | 932 return false; |
946 | 933 |
947 string name = BaseFileName(obj_filename); | 934 string name = BaseFileName(obj_filename); |
948 string os = "Linux"; | 935 string os = "Linux"; |
949 string id = FormatIdentifier(identifier); | 936 // Add an extra "0" at the end. PDB files on Windows have an 'age' |
| 937 // number appended to the end of the file identifier; this isn't |
| 938 // really used or necessary on other platforms, but be consistent. |
| 939 string id = FileID::ConvertIdentifierToUUIDString(identifier) + "0"; |
950 | 940 |
951 LoadSymbolsInfo<ElfClass> info(debug_dirs); | 941 LoadSymbolsInfo<ElfClass> info(debug_dirs); |
952 scoped_ptr<Module> module(new Module(name, os, architecture, id)); | 942 scoped_ptr<Module> module(new Module(name, os, architecture, id)); |
953 if (!LoadSymbols<ElfClass>(obj_filename, big_endian, elf_header, | 943 if (!LoadSymbols<ElfClass>(obj_filename, big_endian, elf_header, |
954 !debug_dirs.empty(), &info, | 944 !debug_dirs.empty(), &info, |
955 options, module.get())) { | 945 options, module.get())) { |
956 const string debuglink_file = info.debuglink_file(); | 946 const string debuglink_file = info.debuglink_file(); |
957 if (debuglink_file.empty()) | 947 if (debuglink_file.empty()) |
958 return false; | 948 return false; |
959 | 949 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 MmapWrapper map_wrapper; | 1019 MmapWrapper map_wrapper; |
1030 void* elf_header = NULL; | 1020 void* elf_header = NULL; |
1031 if (!LoadELF(obj_file, &map_wrapper, &elf_header)) | 1021 if (!LoadELF(obj_file, &map_wrapper, &elf_header)) |
1032 return false; | 1022 return false; |
1033 | 1023 |
1034 return ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(elf_header), | 1024 return ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(elf_header), |
1035 obj_file, debug_dirs, options, module); | 1025 obj_file, debug_dirs, options, module); |
1036 } | 1026 } |
1037 | 1027 |
1038 } // namespace google_breakpad | 1028 } // namespace google_breakpad |
OLD | NEW |