| 280 | } |
| 281 | |
| 282 | static StatusCode |
| 283 | parseCoreFileNote(Elf* core, const NoteData& note_data, std::vector<CoreVirtualMap>& result) |
| 284 | { |
| 285 | Elf_Data* data = note_data.data; |
| 286 | assert(data != NULL); |
| 287 | |
| 288 | const size_t ulong_size = gelf_fsize(note_data.elf, ELF_T_ADDR, 1, EV_CURRENT); |
| 289 | if (ulong_size <= 0) { |
| 290 | LOG(ERROR) << "Cannot determine the size of 'long' for ELF file"; |
| 291 | return StatusCode::ERROR; |
| 292 | } |
| 293 | const char* ptr = static_cast<const char*>(data->d_buf); |
| 294 | const char* end = static_cast<const char*>(data->d_buf) + data->d_size; |
| 295 | |
| 296 | uint64_t count, page_size; |
| 297 | read_obj(&ptr, &count, ulong_size); |
| 298 | read_obj(&ptr, &page_size, ulong_size); |
| 299 | |
| 300 | size_t addrsize = gelf_fsize(core, ELF_T_ADDR, 1, EV_CURRENT); |
| 301 | size_t entry_size = 3 * addrsize; // mstart, mend, moffset |
| 302 | uint64_t maxcount = (size_t)(end - ptr) / entry_size; |
| 303 | if (count > maxcount) { |
| 304 | LOG(ERROR) << "Failed to parse file note data: invalid number of entries"; |
| 305 | return StatusCode::ERROR; |
| 306 | } |
| 307 | |
| 308 | // File names are stored at the end of the main table |
| 309 | const char* filename_table_start = ptr + count * entry_size; |
| 310 | const char* filename_table_ptr = filename_table_start; |
| 311 | |
| 312 | for (size_t i = 0; i < count; ++i) { |
| 313 | // Read the data for a single entry |
| 314 | uint64_t mstart, mend, moffset; |
| 315 | read_obj(&ptr, &mstart, ulong_size); |
| 316 | read_obj(&ptr, &mend, ulong_size); |
| 317 | read_obj(&ptr, &moffset, ulong_size); |
| 318 | |
| 319 | // Fetch the corresponding file name from the file name table |
| 320 | std::string filename(filename_table_ptr); |
| 321 | result.emplace_back(CoreVirtualMap{mstart, mend, 0, "", moffset * page_size, "", 0, filename}); |
| 322 | |
| 323 | // Advance the file name table pointer |
| 324 | const char* next_filename = |
| 325 | static_cast<const char*>(memchr(filename_table_ptr, '\0', end - filename_table_ptr)); |
| 326 | if (next_filename == nullptr) { |
| 327 | LOG(ERROR) << "Failed to parse file note data: file name table ended too soon"; |
| 328 | return StatusCode::ERROR; |
| 329 | } |
| 330 | filename_table_ptr = next_filename + 1; |
| 331 | } |
| 332 | return StatusCode::SUCCESS; |
| 333 | } |
| 334 | |
| 335 | const std::vector<CoreVirtualMap> |
| 336 | CoreFileExtractor::extractMappedFiles() const |
no test coverage detected