Name Name::deepCopy() const { Name copiedName(*this); copiedName.m_nameBlock.resetWire(); copiedName.wireEncode(); // "compress" the underlying buffer return copiedName; }
status_t CoreFile::_ReadThreadsNote(const void* data, uint32 dataSize) { if (dataSize < 3 * sizeof(uint32)) { WARNING("Threads note too short\n"); return B_BAD_DATA; } uint32 threadCount = _ReadValue<uint32>(data, dataSize); uint32 entrySize = _ReadValue<uint32>(data, dataSize); uint32 cpuStateSize = _ReadValue<uint32>(data, dataSize); if (cpuStateSize > 1024 * 1024) { WARNING("Threads note: unreasonable CPU state size: %" B_PRIu32 "\n", cpuStateSize); return B_BAD_DATA; } typedef typename ElfClass::NoteThreadEntry Entry; if (threadCount == 0) return B_OK; size_t totalEntrySize = entrySize + cpuStateSize; // check entry size and thread count if (entrySize == 0 || dataSize == 0 || threadCount > dataSize || entrySize > dataSize || cpuStateSize > dataSize || dataSize - 1 < totalEntrySize || threadCount * totalEntrySize >= dataSize) { WARNING("Threads note: too short or invalid entry size (%" B_PRIu32 ")\n", entrySize); return B_BAD_DATA; } // check, if strings are null-terminated const char* strings = (const char*)data + threadCount * totalEntrySize; size_t stringsSize = dataSize - threadCount * totalEntrySize; if (stringsSize == 0 || strings[stringsSize - 1] != '\0') { WARNING("Threads note strings not terminated\n"); return B_BAD_DATA; } for (uint64 i = 0; i < threadCount; i++) { // get entry values Entry entry = {}; _ReadEntry(data, dataSize, entry, entrySize); int32 id = Get(entry.nth_id); int32 state = Get(entry.nth_state); int32 priority = Get(entry.nth_priority); uint64 stackBase = Get(entry.nth_stack_base); uint64 stackEnd = Get(entry.nth_stack_end); // get name if (stringsSize == 0) { WARNING("Thread %" B_PRIu64 " (ID %#" B_PRIx32 ") has no name\n", i, id); continue; } const char* name = strings; size_t nameSize = strlen(name) + 1; strings += nameSize; stringsSize -= nameSize; BString copiedName(name); if (name[0] != '\0' && copiedName.Length() == 0) return B_NO_MEMORY; // create and add thread CoreFileThreadInfo* thread = new(std::nothrow) CoreFileThreadInfo(id, state, priority, stackBase, stackEnd, copiedName); if (thread == NULL || !fThreadInfos.AddItem(thread)) { delete thread; return B_NO_MEMORY; } // get CPU state if (!thread->SetCpuState(data, cpuStateSize)) return B_NO_MEMORY; _Advance(data, dataSize, cpuStateSize); } return B_OK; }
status_t CoreFile::_ReadImagesNote(const void* data, uint32 dataSize) { if (dataSize < 2 * sizeof(uint32)) { WARNING("Images note too short\n"); return B_BAD_DATA; } uint32 imageCount = _ReadValue<uint32>(data, dataSize); uint32 entrySize = _ReadValue<uint32>(data, dataSize); typedef typename ElfClass::NoteImageEntry Entry; if (imageCount == 0) return B_OK; // check entry size and image count if (entrySize == 0 || dataSize == 0 || imageCount > dataSize || dataSize - 1 < entrySize || imageCount * entrySize >= dataSize) { WARNING("Images note: too short or invalid entry size (%" B_PRIu32 ")\n", entrySize); return B_BAD_DATA; } // check, if strings are null-terminated const char* strings = (const char*)data + imageCount * entrySize; size_t stringsSize = dataSize - imageCount * entrySize; if (stringsSize == 0 || strings[stringsSize - 1] != '\0') { WARNING("Images note strings not terminated\n"); return B_BAD_DATA; } for (uint64 i = 0; i < imageCount; i++) { // get entry values Entry entry = {}; _ReadEntry(data, dataSize, entry, entrySize); int32 id = Get(entry.ni_id); int32 type = Get(entry.ni_type); uint64 initRoutine = Get(entry.ni_init_routine); uint64 termRoutine = Get(entry.ni_term_routine); uint64 textBase = Get(entry.ni_text_base); uint64 textSize = Get(entry.ni_text_size); int64 textDelta = Get(entry.ni_text_delta); uint64 dataBase = Get(entry.ni_data_base); uint64 dataSize = Get(entry.ni_data_size); int32 deviceId = Get(entry.ni_device); int64 nodeId = Get(entry.ni_node); uint64 symbolTable = Get(entry.ni_symbol_table); uint64 symbolHash = Get(entry.ni_symbol_hash); uint64 stringTable = Get(entry.ni_string_table); // get name if (stringsSize == 0) { WARNING("Image %" B_PRIu64 " (ID %#" B_PRIx32 ") has no name\n", i, id); continue; } const char* name = strings; size_t nameSize = strlen(name) + 1; strings += nameSize; stringsSize -= nameSize; BString copiedName(name); if (name[0] != '\0' && copiedName.Length() == 0) return B_NO_MEMORY; // create and add image CoreFileAreaInfo* textArea = _FindArea(textBase); CoreFileAreaInfo* dataArea = _FindArea(dataBase); CoreFileImageInfo* image = new(std::nothrow) CoreFileImageInfo(id, type, initRoutine, termRoutine, textBase, textSize, textDelta, dataBase, dataSize, deviceId, nodeId, symbolTable, symbolHash, stringTable, textArea, dataArea, copiedName); if (image == NULL || !fImageInfos.AddItem(image)) { delete image; return B_NO_MEMORY; } } return B_OK; }
status_t CoreFile::_ReadAreasNote(const void* data, uint32 dataSize) { if (dataSize < 2 * sizeof(uint32)) { WARNING("Areas note too short\n"); return B_BAD_DATA; } uint32 areaCount = _ReadValue<uint32>(data, dataSize); uint32 entrySize = _ReadValue<uint32>(data, dataSize); typedef typename ElfClass::NoteAreaEntry Entry; if (areaCount == 0) return B_OK; // check entry size and area count if (entrySize == 0 || dataSize == 0 || areaCount > dataSize || dataSize - 1 < entrySize || areaCount * entrySize >= dataSize) { WARNING("Areas note: too short or invalid entry size (%" B_PRIu32 ")\n", entrySize); return B_BAD_DATA; } // check, if strings are null-terminated const char* strings = (const char*)data + areaCount * entrySize; size_t stringsSize = dataSize - areaCount * entrySize; if (stringsSize == 0 || strings[stringsSize - 1] != '\0') { WARNING("Areas note strings not terminated\n"); return B_BAD_DATA; } for (uint64 i = 0; i < areaCount; i++) { // get entry values Entry entry = {}; _ReadEntry(data, dataSize, entry, entrySize); int32 id = Get(entry.na_id); uint64 baseAddress = Get(entry.na_base); uint64 size = Get(entry.na_size); uint64 ramSize = Get(entry.na_ram_size); uint32 lock = Get(entry.na_lock); uint32 protection = Get(entry.na_protection); // get name if (stringsSize == 0) { WARNING("Area %" B_PRIu64 " (ID %#" B_PRIx32 " @ %#" B_PRIx64 ") has no name\n", i, id, baseAddress); continue; } const char* name = strings; size_t nameSize = strlen(name) + 1; strings += nameSize; stringsSize -= nameSize; BString copiedName(name); if (name[0] != '\0' && copiedName.Length() == 0) return B_NO_MEMORY; // create and add area ElfSegment* segment = _FindAreaSegment(baseAddress); if (segment == NULL) { WARNING("No matching segment found for area %" B_PRIu64 " (ID %#" B_PRIx32 " @ %#" B_PRIx64 ", name: '%s')", i, id, baseAddress, name); continue; } CoreFileAreaInfo* area = new(std::nothrow) CoreFileAreaInfo(segment, id, baseAddress, size, ramSize, lock, protection, copiedName); if (area == NULL || !fAreaInfos.AddItem(area)) { delete area; return B_NO_MEMORY; } } return B_OK; }