================ @@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP &core_file) const { return error; } -size_t MinidumpFileBuilder::GetDirectoriesNum() const { - return m_directories.size(); +static size_t GetLargestRange(const Process::CoreFileMemoryRanges &ranges) { + size_t max_size = 0; + for (const auto &core_range : ranges) { + max_size = std::max(max_size, core_range.range.size()); + } + return max_size; } -size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const { - return sizeof(llvm::minidump::Header) + m_data.GetByteSize(); +Status MinidumpFileBuilder::AddMemoryList_32( + Process::CoreFileMemoryRanges &ranges) { + std::vector<MemoryDescriptor> descriptors; + Status error; + if (ranges.size() == 0) + return error; + + Log *log = GetLog(LLDBLog::Object); + size_t region_index = 0; + auto data_up = std::make_unique<DataBufferHeap>(GetLargestRange(ranges), 0); + for (const auto &core_range : ranges) { + // Take the offset before we write. + const size_t offset_for_data = GetCurrentDataEndOffset(); + const addr_t addr = core_range.range.start(); + const addr_t size = core_range.range.size(); + const addr_t end = core_range.range.end(); + + LLDB_LOGF(log, + "AddMemoryList %zu/%zu reading memory for region " + "(%zu bytes) [%zx, %zx)", + region_index, ranges.size(), size, addr, addr + size); + ++region_index; + + const size_t bytes_read = + m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error); + if (error.Fail() || bytes_read == 0) { + LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: %s", + bytes_read, error.AsCString()); + // Just skip sections with errors or zero bytes in 32b mode + continue; + } else if (bytes_read != size) { + LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr, + size); + } + + MemoryDescriptor descriptor; + descriptor.StartOfMemoryRange = + static_cast<llvm::support::ulittle64_t>(addr); + descriptor.Memory.DataSize = + static_cast<llvm::support::ulittle32_t>(bytes_read); + descriptor.Memory.RVA = + static_cast<llvm::support::ulittle32_t>(offset_for_data); + descriptors.push_back(descriptor); + if (m_thread_by_range_end.count(end) > 0) + m_thread_by_range_end[end].Stack = descriptor; + + // Add the data to the buffer, flush as needed. + error = AddData(data_up->GetBytes(), bytes_read); + if (error.Fail()) + return error; + } + + // Add a directory that references this list + // With a size of the number of ranges as a 32 bit num + // And then the size of all the ranges + error = AddDirectory(StreamType::MemoryList, + sizeof(llvm::support::ulittle32_t) + + descriptors.size() * + sizeof(llvm::minidump::MemoryDescriptor)); + if (error.Fail()) + return error; + + llvm::support::ulittle32_t memory_ranges_num = + static_cast<llvm::support::ulittle32_t>(descriptors.size()); + m_data.AppendData(&memory_ranges_num, sizeof(llvm::support::ulittle32_t)); + // For 32b we can get away with writing off the descriptors after the data. + // This means no cleanup loop needed. + m_data.AppendData(descriptors.data(), + descriptors.size() * sizeof(MemoryDescriptor)); + + return error; +} + +Status MinidumpFileBuilder::AddMemoryList_64( + Process::CoreFileMemoryRanges &ranges) { + Status error; + if (ranges.empty()) + return error; + + error = AddDirectory(StreamType::Memory64List, + (sizeof(llvm::support::ulittle64_t) * 2) + + ranges.size() * sizeof(llvm::minidump::MemoryDescriptor_64)); + if (error.Fail()) + return error; + + llvm::support::ulittle64_t memory_ranges_num = + static_cast<llvm::support::ulittle64_t>(ranges.size()); + m_data.AppendData(&memory_ranges_num, sizeof(llvm::support::ulittle64_t)); + // Capture the starting offset for all the descriptors so we can clean them up + // if needed. + offset_t starting_offset = GetCurrentDataEndOffset() + sizeof(llvm::support::ulittle64_t); + // The base_rva needs to start after the directories, which is right after + // this 8 byte variable. + offset_t base_rva = starting_offset + (ranges.size() * sizeof(llvm::minidump::MemoryDescriptor_64)); + llvm::support::ulittle64_t memory_ranges_base_rva = + static_cast<llvm::support::ulittle64_t>(base_rva); ---------------- clayborg wrote:
no static cast https://github.com/llvm/llvm-project/pull/95312 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits