diff options
Diffstat (limited to 'src/common/linux/file_id.cc')
-rw-r--r-- | src/common/linux/file_id.cc | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc index 00b37313..e8dc528d 100644 --- a/src/common/linux/file_id.cc +++ b/src/common/linux/file_id.cc @@ -39,6 +39,7 @@ #include <string.h> #include <algorithm> +#include <string> #include "common/linux/elf_gnu_compat.h" #include "common/linux/elfutils.h" @@ -46,8 +47,13 @@ #include "common/linux/memory_mapped_file.h" #include "third_party/lss/linux_syscall_support.h" +using std::string; + namespace google_breakpad { +// Used in a few places for backwards-compatibility. +const size_t kMDGUIDSize = sizeof(MDGUID); + FileID::FileID(const char* path) : path_(path) {} // ELF note name and desc are 32-bits word padded. @@ -58,7 +64,7 @@ FileID::FileID(const char* path) : path_(path) {} template<typename ElfClass> static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length, - uint8_t identifier[kMDGUIDSize]) { + wasteful_vector<uint8_t>& identifier) { typedef typename ElfClass::Nhdr Nhdr; const void* section_end = reinterpret_cast<const char*>(section) + length; @@ -76,21 +82,19 @@ static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length, return false; } - const char* build_id = reinterpret_cast<const char*>(note_header) + + const uint8_t* build_id = reinterpret_cast<const uint8_t*>(note_header) + sizeof(Nhdr) + NOTE_PADDING(note_header->n_namesz); - // Copy as many bits of the build ID as will fit - // into the GUID space. - my_memset(identifier, 0, kMDGUIDSize); - memcpy(identifier, build_id, - std::min(kMDGUIDSize, (size_t)note_header->n_descsz)); + identifier.insert(identifier.end(), + build_id, + build_id + note_header->n_descsz); return true; } // Attempt to locate a .note.gnu.build-id section in an ELF binary -// and copy as many bytes of it as will fit into |identifier|. -static bool FindElfBuildIDNote(const void *elf_mapped_base, - uint8_t identifier[kMDGUIDSize]) { +// and copy it into |identifier|. +static bool FindElfBuildIDNote(const void* elf_mapped_base, + wasteful_vector<uint8_t>& identifier) { void* note_section; size_t note_size; int elfclass; @@ -116,8 +120,10 @@ static bool FindElfBuildIDNote(const void *elf_mapped_base, // Attempt to locate the .text section of an ELF binary and generate // a simple hash by XORing the first page worth of bytes into |identifier|. -static bool HashElfTextSection(const void *elf_mapped_base, - uint8_t identifier[kMDGUIDSize]) { +static bool HashElfTextSection(const void* elf_mapped_base, + wasteful_vector<uint8_t>& identifier) { + identifier.resize(kMDGUIDSize); + void* text_section; size_t text_size; if (!FindElfSection(elf_mapped_base, ".text", SHT_PROGBITS, @@ -126,7 +132,9 @@ static bool HashElfTextSection(const void *elf_mapped_base, return false; } - my_memset(identifier, 0, kMDGUIDSize); + // Only provide |kMDGUIDSize| bytes to keep identifiers produced by this + // function backwards-compatible. + my_memset(&identifier[0], 0, kMDGUIDSize); const uint8_t* ptr = reinterpret_cast<const uint8_t*>(text_section); const uint8_t* ptr_end = ptr + std::min(text_size, static_cast<size_t>(4096)); while (ptr < ptr_end) { @@ -139,7 +147,7 @@ static bool HashElfTextSection(const void *elf_mapped_base, // static bool FileID::ElfFileIdentifierFromMappedFile(const void* base, - uint8_t identifier[kMDGUIDSize]) { + wasteful_vector<uint8_t>& identifier) { // Look for a build id note first. if (FindElfBuildIDNote(base, identifier)) return true; @@ -148,7 +156,7 @@ bool FileID::ElfFileIdentifierFromMappedFile(const void* base, return HashElfTextSection(base, identifier); } -bool FileID::ElfFileIdentifier(uint8_t identifier[kMDGUIDSize]) { +bool FileID::ElfFileIdentifier(wasteful_vector<uint8_t>& identifier) { MemoryMappedFile mapped_file(path_.c_str(), 0); if (!mapped_file.data()) // Should probably check if size >= ElfW(Ehdr)? return false; @@ -156,13 +164,16 @@ bool FileID::ElfFileIdentifier(uint8_t identifier[kMDGUIDSize]) { return ElfFileIdentifierFromMappedFile(mapped_file.data(), identifier); } +// This function is not ever called in an unsafe context, so it's OK +// to allocate memory and use libc. // static -void FileID::ConvertIdentifierToString(const uint8_t identifier[kMDGUIDSize], - char* buffer, int buffer_length) { - uint8_t identifier_swapped[kMDGUIDSize]; +string FileID::ConvertIdentifierToUUIDString( + const wasteful_vector<uint8_t>& identifier) { + uint8_t identifier_swapped[kMDGUIDSize] = { 0 }; // Endian-ness swap to match dump processor expectation. - memcpy(identifier_swapped, identifier, kMDGUIDSize); + memcpy(identifier_swapped, &identifier[0], + std::min(kMDGUIDSize, identifier.size())); uint32_t* data1 = reinterpret_cast<uint32_t*>(identifier_swapped); *data1 = htonl(*data1); uint16_t* data2 = reinterpret_cast<uint16_t*>(identifier_swapped + 4); @@ -170,22 +181,13 @@ void FileID::ConvertIdentifierToString(const uint8_t identifier[kMDGUIDSize], uint16_t* data3 = reinterpret_cast<uint16_t*>(identifier_swapped + 6); *data3 = htons(*data3); - int buffer_idx = 0; - for (unsigned int idx = 0; - (buffer_idx < buffer_length) && (idx < kMDGUIDSize); - ++idx) { - int hi = (identifier_swapped[idx] >> 4) & 0x0F; - int lo = (identifier_swapped[idx]) & 0x0F; - - if (idx == 4 || idx == 6 || idx == 8 || idx == 10) - buffer[buffer_idx++] = '-'; - - buffer[buffer_idx++] = (hi >= 10) ? 'A' + hi - 10 : '0' + hi; - buffer[buffer_idx++] = (lo >= 10) ? 'A' + lo - 10 : '0' + lo; + string result; + for (unsigned int idx = 0; idx < kMDGUIDSize; ++idx) { + char buf[3]; + snprintf(buf, sizeof(buf), "%02X", identifier_swapped[idx]); + result.append(buf); } - - // NULL terminate - buffer[(buffer_idx < buffer_length) ? buffer_idx : buffer_idx - 1] = 0; + return result; } } // namespace google_breakpad |