void BlockAllocator::Block::SetTag(const char *_tag) { if (_tag) truncate_cpy(tag, _tag); else truncate_cpy(tag, "---"); }
void SymbolMap::AddLabel(const char* name, u32 address, int moduleIndex) { std::lock_guard<std::recursive_mutex> guard(lock_); if (moduleIndex == -1) { moduleIndex = GetModuleIndex(address); } else if (moduleIndex == 0) { sawUnknownModule = true; } // Is there an existing one? u32 relAddress = GetModuleRelativeAddr(address, moduleIndex); auto symbolKey = std::make_pair(moduleIndex, relAddress); auto existing = labels.find(symbolKey); if (sawUnknownModule && existing == labels.end()) { // Fall back: maybe it's got moduleIndex = 0. existing = labels.find(std::make_pair(0, address)); } if (existing != labels.end()) { // We leave an existing label alone, rather than overwriting. // But we'll still upgrade it to the correct module / relative address. if (existing->second.module != moduleIndex) { LabelEntry label = existing->second; label.addr = relAddress; label.module = moduleIndex; labels.erase(existing); labels[symbolKey] = label; // Refresh the active item if it exists. auto active = activeLabels.find(address); if (active != activeLabels.end() && active->second.module == moduleIndex) { activeLabels.erase(active); activeLabels.insert(std::make_pair(address, label)); } } } else { LabelEntry label; label.addr = relAddress; label.module = moduleIndex; truncate_cpy(label.name, name); labels[symbolKey] = label; if (IsModuleActive(moduleIndex)) { activeLabels.insert(std::make_pair(address, label)); } } }
void SymbolMap::SetLabelName(const char* name, u32 address) { if (activeNeedUpdate_) UpdateActiveSymbols(); std::lock_guard<std::recursive_mutex> guard(lock_); auto labelInfo = activeLabels.find(address); if (labelInfo == activeLabels.end()) { AddLabel(name, address); } else { auto symbolKey = std::make_pair(labelInfo->second.module, labelInfo->second.addr); auto label = labels.find(symbolKey); if (label != labels.end()) { truncate_cpy(label->second.name, name); label->second.name[127] = 0; // Refresh the active item if it exists. auto active = activeLabels.find(address); if (active != activeLabels.end() && active->second.module == label->second.module) { activeLabels.erase(active); activeLabels.insert(std::make_pair(address, label->second)); } } } }
void SymbolMap::AddModule(const char *name, u32 address, u32 size) { std::lock_guard<std::recursive_mutex> guard(lock_); for (auto it = modules.begin(), end = modules.end(); it != end; ++it) { if (!strcmp(it->name, name)) { // Just reactivate that one. it->start = address; it->size = size; activeModuleEnds.insert(std::make_pair(it->start + it->size, *it)); activeNeedUpdate_ = true; return; } } ModuleEntry mod; truncate_cpy(mod.name, name); mod.start = address; mod.size = size; mod.index = (int)modules.size() + 1; modules.push_back(mod); activeModuleEnds.insert(std::make_pair(mod.start + mod.size, mod)); activeNeedUpdate_ = true; }
// Takes ownership of buffer. CChunkFileReader::Error CChunkFileReader::SaveFile(const std::string &filename, const std::string &title, const char *gitVersion, u8 *buffer, size_t sz) { INFO_LOG(SAVESTATE, "ChunkReader: Writing %s", filename.c_str()); File::IOFile pFile(filename, "wb"); if (!pFile) { ERROR_LOG(SAVESTATE, "ChunkReader: Error opening file for write"); free(buffer); return ERROR_BAD_FILE; } // Make sure we can allocate a buffer to compress before compressing. size_t write_len = snappy_max_compressed_length(sz); u8 *compressed_buffer = (u8 *)malloc(write_len); u8 *write_buffer = buffer; if (!compressed_buffer) { ERROR_LOG(SAVESTATE, "ChunkReader: Unable to allocate compressed buffer"); // We'll save uncompressed. Better than not saving... write_len = sz; } else { snappy_compress((const char *)buffer, sz, (char *)compressed_buffer, &write_len); free(buffer); write_buffer = compressed_buffer; } // Create header SChunkHeader header; header.Compress = compressed_buffer ? 1 : 0; header.Revision = REVISION_CURRENT; header.ExpectedSize = (u32)write_len; header.UncompressedSize = (u32)sz; truncate_cpy(header.GitVersion, gitVersion); // Setup the fixed-length title. char titleFixed[128]; truncate_cpy(titleFixed, title.c_str()); // Now let's start writing out the file... if (!pFile.WriteArray(&header, 1)) { ERROR_LOG(SAVESTATE, "ChunkReader: Failed writing header"); free(write_buffer); return ERROR_BAD_FILE; } if (!pFile.WriteArray(titleFixed, sizeof(titleFixed))) { ERROR_LOG(SAVESTATE, "ChunkReader: Failed writing title"); free(write_buffer); return ERROR_BAD_FILE; } if (!pFile.WriteBytes(write_buffer, write_len)) { ERROR_LOG(SAVESTATE, "ChunkReader: Failed writing compressed data"); free(write_buffer); return ERROR_BAD_FILE; } else if (sz != write_len) { INFO_LOG(SAVESTATE, "Savestate: Compressed %i bytes into %i", (int)sz, (int)write_len); } free(write_buffer); INFO_LOG(SAVESTATE, "ChunkReader: Done writing %s", filename.c_str()); return ERROR_NONE; }
BlockAllocator::Block::Block(u32 _start, u32 _size, bool _taken, Block *_prev, Block *_next) : start(_start), size(_size), taken(_taken), prev(_prev), next(_next) { truncate_cpy(tag, "(untitled)"); }