| 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 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 return false; | 894 return false; |
| 895 if (debug_big_endian != obj_file_is_big_endian) { | 895 if (debug_big_endian != obj_file_is_big_endian) { |
| 896 fprintf(stderr, "%s and %s does not match in endianness\n", | 896 fprintf(stderr, "%s and %s does not match in endianness\n", |
| 897 obj_filename.c_str(), debuglink_file.c_str()); | 897 obj_filename.c_str(), debuglink_file.c_str()); |
| 898 return false; | 898 return false; |
| 899 } | 899 } |
| 900 return true; | 900 return true; |
| 901 } | 901 } |
| 902 | 902 |
| 903 template<typename ElfClass> | 903 template<typename ElfClass> |
| 904 bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, | 904 bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header, |
| 905 const string& obj_filename, | 905 const string& obj_filename, |
| 906 const std::vector<string>& debug_dirs, | 906 scoped_ptr<Module>& module) { |
| 907 const DumpOptions& options, | |
| 908 Module** out_module) { | |
| 909 typedef typename ElfClass::Ehdr Ehdr; | |
| 910 | |
| 911 *out_module = NULL; | |
| 912 | |
| 913 PageAllocator allocator; | 907 PageAllocator allocator; |
| 914 wasteful_vector<uint8_t> identifier(&allocator, kDefaultBuildIdSize); | 908 wasteful_vector<uint8_t> identifier(&allocator, kDefaultBuildIdSize); |
| 915 if (!FileID::ElfFileIdentifierFromMappedFile(elf_header, | 909 if (!FileID::ElfFileIdentifierFromMappedFile(elf_header, identifier)) { |
| 916 identifier)) { | |
| 917 fprintf(stderr, "%s: unable to generate file identifier\n", | 910 fprintf(stderr, "%s: unable to generate file identifier\n", |
| 918 obj_filename.c_str()); | 911 obj_filename.c_str()); |
| 919 return false; | 912 return false; |
| 920 } | 913 } |
| 921 | 914 |
| 922 const char *architecture = ElfArchitecture<ElfClass>(elf_header); | 915 const char *architecture = ElfArchitecture<ElfClass>(elf_header); |
| 923 if (!architecture) { | 916 if (!architecture) { |
| 924 fprintf(stderr, "%s: unrecognized ELF machine architecture: %d\n", | 917 fprintf(stderr, "%s: unrecognized ELF machine architecture: %d\n", |
| 925 obj_filename.c_str(), elf_header->e_machine); | 918 obj_filename.c_str(), elf_header->e_machine); |
| 926 return false; | 919 return false; |
| 927 } | 920 } |
| 928 | 921 |
| 929 // Figure out what endianness this file is. | |
| 930 bool big_endian; | |
| 931 if (!ElfEndianness<ElfClass>(elf_header, &big_endian)) | |
| 932 return false; | |
| 933 | |
| 934 string name = BaseFileName(obj_filename); | 922 string name = BaseFileName(obj_filename); |
| 935 string os = "Linux"; | 923 string os = "Linux"; |
| 936 // Add an extra "0" at the end. PDB files on Windows have an 'age' | 924 // 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 | 925 // number appended to the end of the file identifier; this isn't |
| 938 // really used or necessary on other platforms, but be consistent. | 926 // really used or necessary on other platforms, but be consistent. |
| 939 string id = FileID::ConvertIdentifierToUUIDString(identifier) + "0"; | 927 string id = FileID::ConvertIdentifierToUUIDString(identifier) + "0"; |
| 940 | 928 |
| 929 module.reset(new Module(name, os, architecture, id)); |
| 930 |
| 931 return true; |
| 932 } |
| 933 |
| 934 template<typename ElfClass> |
| 935 bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, |
| 936 const string& obj_filename, |
| 937 const std::vector<string>& debug_dirs, |
| 938 const DumpOptions& options, |
| 939 Module** out_module) { |
| 940 typedef typename ElfClass::Ehdr Ehdr; |
| 941 |
| 942 *out_module = NULL; |
| 943 |
| 944 scoped_ptr<Module> module; |
| 945 if (!InitModuleForElfClass<ElfClass>(elf_header, obj_filename, module)) { |
| 946 return false; |
| 947 } |
| 948 |
| 949 // Figure out what endianness this file is. |
| 950 bool big_endian; |
| 951 if (!ElfEndianness<ElfClass>(elf_header, &big_endian)) |
| 952 return false; |
| 953 |
| 941 LoadSymbolsInfo<ElfClass> info(debug_dirs); | 954 LoadSymbolsInfo<ElfClass> info(debug_dirs); |
| 942 scoped_ptr<Module> module(new Module(name, os, architecture, id)); | |
| 943 if (!LoadSymbols<ElfClass>(obj_filename, big_endian, elf_header, | 955 if (!LoadSymbols<ElfClass>(obj_filename, big_endian, elf_header, |
| 944 !debug_dirs.empty(), &info, | 956 !debug_dirs.empty(), &info, |
| 945 options, module.get())) { | 957 options, module.get())) { |
| 946 const string debuglink_file = info.debuglink_file(); | 958 const string debuglink_file = info.debuglink_file(); |
| 947 if (debuglink_file.empty()) | 959 if (debuglink_file.empty()) |
| 948 return false; | 960 return false; |
| 949 | 961 |
| 950 // Load debuglink ELF file. | 962 // Load debuglink ELF file. |
| 951 fprintf(stderr, "Found debugging info in %s\n", debuglink_file.c_str()); | 963 fprintf(stderr, "Found debugging info in %s\n", debuglink_file.c_str()); |
| 952 MmapWrapper debug_map_wrapper; | 964 MmapWrapper debug_map_wrapper; |
| 953 Ehdr* debug_elf_header = NULL; | 965 Ehdr* debug_elf_header = NULL; |
| 954 if (!LoadELF(debuglink_file, &debug_map_wrapper, | 966 if (!LoadELF(debuglink_file, &debug_map_wrapper, |
| 955 reinterpret_cast<void**>(&debug_elf_header)) || | 967 reinterpret_cast<void**>(&debug_elf_header)) || |
| 956 !SanitizeDebugFile<ElfClass>(debug_elf_header, debuglink_file, | 968 !SanitizeDebugFile<ElfClass>(debug_elf_header, debuglink_file, |
| 957 obj_filename, architecture, big_endian)) { | 969 obj_filename, |
| 970 module->architecture().c_str(), |
| 971 big_endian)) { |
| 958 return false; | 972 return false; |
| 959 } | 973 } |
| 960 | 974 |
| 961 if (!LoadSymbols<ElfClass>(debuglink_file, big_endian, | 975 if (!LoadSymbols<ElfClass>(debuglink_file, big_endian, |
| 962 debug_elf_header, false, &info, | 976 debug_elf_header, false, &info, |
| 963 options, module.get())) { | 977 options, module.get())) { |
| 964 return false; | 978 return false; |
| 965 } | 979 } |
| 966 } | 980 } |
| 967 | 981 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 std::ostream &sym_stream) { | 1019 std::ostream &sym_stream) { |
| 1006 Module* module; | 1020 Module* module; |
| 1007 if (!ReadSymbolData(obj_file, debug_dirs, options, &module)) | 1021 if (!ReadSymbolData(obj_file, debug_dirs, options, &module)) |
| 1008 return false; | 1022 return false; |
| 1009 | 1023 |
| 1010 bool result = module->Write(sym_stream, options.symbol_data); | 1024 bool result = module->Write(sym_stream, options.symbol_data); |
| 1011 delete module; | 1025 delete module; |
| 1012 return result; | 1026 return result; |
| 1013 } | 1027 } |
| 1014 | 1028 |
| 1029 // Read the selected object file's debugging information, and write out the |
| 1030 // header only to |stream|. Return true on success; if an error occurs, report |
| 1031 // it and return false. |
| 1032 bool WriteSymbolFileHeader(const string& obj_file, |
| 1033 std::ostream &sym_stream) { |
| 1034 MmapWrapper map_wrapper; |
| 1035 void* elf_header = NULL; |
| 1036 if (!LoadELF(obj_file, &map_wrapper, &elf_header)) { |
| 1037 fprintf(stderr, "Could not load ELF file: %s\n", obj_file.c_str()); |
| 1038 return false; |
| 1039 } |
| 1040 |
| 1041 if (!IsValidElf(elf_header)) { |
| 1042 fprintf(stderr, "Not a valid ELF file: %s\n", obj_file.c_str()); |
| 1043 return false; |
| 1044 } |
| 1045 |
| 1046 int elfclass = ElfClass(elf_header); |
| 1047 scoped_ptr<Module> module; |
| 1048 if (elfclass == ELFCLASS32) { |
| 1049 if (!InitModuleForElfClass<ElfClass32>( |
| 1050 reinterpret_cast<const Elf32_Ehdr*>(elf_header), obj_file, module)) { |
| 1051 fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str()); |
| 1052 return false; |
| 1053 } |
| 1054 } else if (elfclass == ELFCLASS64) { |
| 1055 if (!InitModuleForElfClass<ElfClass64>( |
| 1056 reinterpret_cast<const Elf64_Ehdr*>(elf_header), obj_file, module)) { |
| 1057 fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str()); |
| 1058 return false; |
| 1059 } |
| 1060 } else { |
| 1061 fprintf(stderr, "Unsupported module file: %s\n", obj_file.c_str()); |
| 1062 return false; |
| 1063 } |
| 1064 |
| 1065 return module->Write(sym_stream, ALL_SYMBOL_DATA); |
| 1066 } |
| 1067 |
| 1015 bool ReadSymbolData(const string& obj_file, | 1068 bool ReadSymbolData(const string& obj_file, |
| 1016 const std::vector<string>& debug_dirs, | 1069 const std::vector<string>& debug_dirs, |
| 1017 const DumpOptions& options, | 1070 const DumpOptions& options, |
| 1018 Module** module) { | 1071 Module** module) { |
| 1019 MmapWrapper map_wrapper; | 1072 MmapWrapper map_wrapper; |
| 1020 void* elf_header = NULL; | 1073 void* elf_header = NULL; |
| 1021 if (!LoadELF(obj_file, &map_wrapper, &elf_header)) | 1074 if (!LoadELF(obj_file, &map_wrapper, &elf_header)) |
| 1022 return false; | 1075 return false; |
| 1023 | 1076 |
| 1024 return ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(elf_header), | 1077 return ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(elf_header), |
| 1025 obj_file, debug_dirs, options, module); | 1078 obj_file, debug_dirs, options, module); |
| 1026 } | 1079 } |
| 1027 | 1080 |
| 1028 } // namespace google_breakpad | 1081 } // namespace google_breakpad |
| OLD | NEW |