diff options
author | ted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2013-04-04 16:24:52 +0000 |
---|---|---|
committer | ted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2013-04-04 16:24:52 +0000 |
commit | b6e66b294fe5d851ffbb57c1527acccf2f53a4b5 (patch) | |
tree | d9393dd09c9dff808df5053667fd6a7f20d69226 /src/common/linux/file_id.cc | |
parent | Support generic Elf notes, with unit tests (diff) | |
download | breakpad-b6e66b294fe5d851ffbb57c1527acccf2f53a4b5.tar.xz |
Try to find a build-id through PT_NOTE program headers
A=Mike Hommey <mh@glandium.org>
R=ted at https://breakpad.appspot.com/544003/
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1143 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/linux/file_id.cc')
-rw-r--r-- | src/common/linux/file_id.cc | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc index 4e380b06..ca5a3e1f 100644 --- a/src/common/linux/file_id.cc +++ b/src/common/linux/file_id.cc @@ -55,22 +55,34 @@ FileID::FileID(const char* path) { strncpy(path_, path, sizeof(path_)); } -// These six functions are also used inside the crashed process, so be safe +// ELF note name and desc are 32-bits word padded. +#define NOTE_PADDING(a) ((a + 3) & ~3) + +// These functions are also used inside the crashed process, so be safe // and use the syscall/libc wrappers instead of direct syscalls or libc. template<typename ElfClass> -static bool ElfClassBuildIDNoteIdentifier(const void *section, +static bool ElfClassBuildIDNoteIdentifier(const void *section, int length, uint8_t identifier[kMDGUIDSize]) { typedef typename ElfClass::Nhdr Nhdr; + const void* section_end = reinterpret_cast<const char*>(section) + length; const Nhdr* note_header = reinterpret_cast<const Nhdr*>(section); - if (note_header->n_type != NT_GNU_BUILD_ID || + while (reinterpret_cast<const void *>(note_header) < section_end) { + if (note_header->n_type == NT_GNU_BUILD_ID) + break; + note_header = reinterpret_cast<const Nhdr*>( + reinterpret_cast<const char*>(note_header) + sizeof(Nhdr) + + NOTE_PADDING(note_header->n_namesz) + + NOTE_PADDING(note_header->n_descsz)); + } + if (reinterpret_cast<const void *>(note_header) >= section_end || note_header->n_descsz == 0) { return false; } - const char* build_id = reinterpret_cast<const char*>(section) + - sizeof(Nhdr) + note_header->n_namesz; + const char* build_id = reinterpret_cast<const char*>(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); @@ -86,16 +98,21 @@ static bool FindElfBuildIDNote(const void *elf_mapped_base, uint8_t identifier[kMDGUIDSize]) { void* note_section; int note_size, elfclass; - if (!FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE, - (const void**)¬e_section, ¬e_size, &elfclass) || - note_size == 0) { + if ((!FindElfSegment(elf_mapped_base, PT_NOTE, + (const void**)¬e_section, ¬e_size, &elfclass) || + note_size == 0) && + (!FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE, + (const void**)¬e_section, ¬e_size, &elfclass) || + note_size == 0)) { return false; } if (elfclass == ELFCLASS32) { - return ElfClassBuildIDNoteIdentifier<ElfClass32>(note_section, identifier); + return ElfClassBuildIDNoteIdentifier<ElfClass32>(note_section, note_size, + identifier); } else if (elfclass == ELFCLASS64) { - return ElfClassBuildIDNoteIdentifier<ElfClass64>(note_section, identifier); + return ElfClassBuildIDNoteIdentifier<ElfClass64>(note_section, note_size, + identifier); } return false; |