LEFT | RIGHT |
1 // Copyright (c) 2006, Google Inc. | 1 // Copyright (c) 2006, 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 | 50 |
51 FileID::FileID(const char* path) : path_(path) {} | 51 FileID::FileID(const char* path) : path_(path) {} |
52 | 52 |
53 // ELF note name and desc are 32-bits word padded. | 53 // ELF note name and desc are 32-bits word padded. |
54 #define NOTE_PADDING(a) ((a + 3) & ~3) | 54 #define NOTE_PADDING(a) ((a + 3) & ~3) |
55 | 55 |
56 // These functions are also used inside the crashed process, so be safe | 56 // These functions are also used inside the crashed process, so be safe |
57 // and use the syscall/libc wrappers instead of direct syscalls or libc. | 57 // and use the syscall/libc wrappers instead of direct syscalls or libc. |
58 | 58 |
59 template<typename ElfClass> | 59 template<typename ElfClass> |
60 static bool ElfClassBuildIDNoteIdentifier(const void *section, int length, | 60 static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length, |
61 uint8_t identifier[kMDGUIDSize]) { | 61 uint8_t identifier[kMDGUIDSize]) { |
62 typedef typename ElfClass::Nhdr Nhdr; | 62 typedef typename ElfClass::Nhdr Nhdr; |
63 | 63 |
64 const void* section_end = reinterpret_cast<const char*>(section) + length; | 64 const void* section_end = reinterpret_cast<const char*>(section) + length; |
65 const Nhdr* note_header = reinterpret_cast<const Nhdr*>(section); | 65 const Nhdr* note_header = reinterpret_cast<const Nhdr*>(section); |
66 while (reinterpret_cast<const void *>(note_header) < section_end) { | 66 while (reinterpret_cast<const void *>(note_header) < section_end) { |
67 if (note_header->n_type == NT_GNU_BUILD_ID) | 67 if (note_header->n_type == NT_GNU_BUILD_ID) |
68 break; | 68 break; |
69 note_header = reinterpret_cast<const Nhdr*>( | 69 note_header = reinterpret_cast<const Nhdr*>( |
70 reinterpret_cast<const char*>(note_header) + sizeof(Nhdr) + | 70 reinterpret_cast<const char*>(note_header) + sizeof(Nhdr) + |
(...skipping 14 matching lines...) Expand all Loading... |
85 std::min(kMDGUIDSize, (size_t)note_header->n_descsz)); | 85 std::min(kMDGUIDSize, (size_t)note_header->n_descsz)); |
86 | 86 |
87 return true; | 87 return true; |
88 } | 88 } |
89 | 89 |
90 // Attempt to locate a .note.gnu.build-id section in an ELF binary | 90 // Attempt to locate a .note.gnu.build-id section in an ELF binary |
91 // and copy as many bytes of it as will fit into |identifier|. | 91 // and copy as many bytes of it as will fit into |identifier|. |
92 static bool FindElfBuildIDNote(const void *elf_mapped_base, | 92 static bool FindElfBuildIDNote(const void *elf_mapped_base, |
93 uint8_t identifier[kMDGUIDSize]) { | 93 uint8_t identifier[kMDGUIDSize]) { |
94 void* note_section; | 94 void* note_section; |
95 int note_size, elfclass; | 95 size_t note_size; |
| 96 int elfclass; |
96 if ((!FindElfSegment(elf_mapped_base, PT_NOTE, | 97 if ((!FindElfSegment(elf_mapped_base, PT_NOTE, |
97 (const void**)¬e_section, ¬e_size, &elfclass) || | 98 (const void**)¬e_section, ¬e_size, &elfclass) || |
98 note_size == 0) && | 99 note_size == 0) && |
99 (!FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE, | 100 (!FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE, |
100 (const void**)¬e_section, ¬e_size, &elfclass) || | 101 (const void**)¬e_section, ¬e_size, &elfclass) || |
101 note_size == 0)) { | 102 note_size == 0)) { |
102 return false; | 103 return false; |
103 } | 104 } |
104 | 105 |
105 if (elfclass == ELFCLASS32) { | 106 if (elfclass == ELFCLASS32) { |
106 return ElfClassBuildIDNoteIdentifier<ElfClass32>(note_section, note_size, | 107 return ElfClassBuildIDNoteIdentifier<ElfClass32>(note_section, note_size, |
107 identifier); | 108 identifier); |
108 } else if (elfclass == ELFCLASS64) { | 109 } else if (elfclass == ELFCLASS64) { |
109 return ElfClassBuildIDNoteIdentifier<ElfClass64>(note_section, note_size, | 110 return ElfClassBuildIDNoteIdentifier<ElfClass64>(note_section, note_size, |
110 identifier); | 111 identifier); |
111 } | 112 } |
112 | 113 |
113 return false; | 114 return false; |
114 } | 115 } |
115 | 116 |
116 // Attempt to locate the .text section of an ELF binary and generate | 117 // Attempt to locate the .text section of an ELF binary and generate |
117 // a simple hash by XORing the first page worth of bytes into |identifier|. | 118 // a simple hash by XORing the first page worth of bytes into |identifier|. |
118 static bool HashElfTextSection(const void *elf_mapped_base, | 119 static bool HashElfTextSection(const void *elf_mapped_base, |
119 uint8_t identifier[kMDGUIDSize]) { | 120 uint8_t identifier[kMDGUIDSize]) { |
120 void* text_section; | 121 void* text_section; |
121 int text_size; | 122 size_t text_size; |
122 if (!FindElfSection(elf_mapped_base, ".text", SHT_PROGBITS, | 123 if (!FindElfSection(elf_mapped_base, ".text", SHT_PROGBITS, |
123 (const void**)&text_section, &text_size, NULL) || | 124 (const void**)&text_section, &text_size, NULL) || |
124 text_size == 0) { | 125 text_size == 0) { |
125 return false; | 126 return false; |
126 } | 127 } |
127 | 128 |
128 my_memset(identifier, 0, kMDGUIDSize); | 129 my_memset(identifier, 0, kMDGUIDSize); |
129 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(text_section); | 130 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(text_section); |
130 const uint8_t* ptr_end = ptr + std::min(text_size, 4096); | 131 const uint8_t* ptr_end = ptr + std::min(text_size, static_cast<size_t>(4096)); |
131 while (ptr < ptr_end) { | 132 while (ptr < ptr_end) { |
132 for (unsigned i = 0; i < kMDGUIDSize; i++) | 133 for (unsigned i = 0; i < kMDGUIDSize; i++) |
133 identifier[i] ^= ptr[i]; | 134 identifier[i] ^= ptr[i]; |
134 ptr += kMDGUIDSize; | 135 ptr += kMDGUIDSize; |
135 } | 136 } |
136 return true; | 137 return true; |
137 } | 138 } |
138 | 139 |
139 // static | 140 // static |
140 bool FileID::ElfFileIdentifierFromMappedFile(const void* base, | 141 bool FileID::ElfFileIdentifierFromMappedFile(const void* base, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 182 |
182 buffer[buffer_idx++] = (hi >= 10) ? 'A' + hi - 10 : '0' + hi; | 183 buffer[buffer_idx++] = (hi >= 10) ? 'A' + hi - 10 : '0' + hi; |
183 buffer[buffer_idx++] = (lo >= 10) ? 'A' + lo - 10 : '0' + lo; | 184 buffer[buffer_idx++] = (lo >= 10) ? 'A' + lo - 10 : '0' + lo; |
184 } | 185 } |
185 | 186 |
186 // NULL terminate | 187 // NULL terminate |
187 buffer[(buffer_idx < buffer_length) ? buffer_idx : buffer_idx - 1] = 0; | 188 buffer[(buffer_idx < buffer_length) ? buffer_idx : buffer_idx - 1] = 0; |
188 } | 189 } |
189 | 190 |
190 } // namespace google_breakpad | 191 } // namespace google_breakpad |
LEFT | RIGHT |