static Retcode modify_translations(Environ *e, Cell virt, Cell size, Int mode) { Translation *t; int changed = 1; /* this is a really sucky algorithm but it works, we modify one */ /* block per pass until no more blocks need to be modified */ while (changed) { changed = 0; for (t = g_translations; t; t = t->next) { if (virt <= t->virt && t->virt < virt + size) { Cell s = (virt + size) - t->virt; Cell p; Cell v; if (s >= t->size) { t->mode = mode; continue; } v = t->virt; p = t->phys; remove_translation(e, v, s); add_translation(e, v, p, s, mode); changed = 1; break; } else if (t->virt < virt && virt < t->virt + t->size) { Cell s = (t->virt + t->size) - virt; Cell p; if (s > size) s = size; p = t->phys + (virt - t->virt); remove_translation(e, virt, s); add_translation(e, virt, p, s, mode); changed = 1; break; } } } return NO_ERROR; }
void RemoveTranslationOptimizerState::update() { if (skip_steps_ == 0 || (call_number_ % skip_steps_) == 0) { remove_translation(); } ++call_number_; }
//Removes translation from translations and strings lists void version_info_editor::remove_translation(const std::wstring& translation) { std::pair<uint16_t, uint16_t> translation_ids(translation_from_string(translation)); remove_translation(translation_ids.first, translation_ids.second); }
Retcode add_translation(Environ *e, uInt phys, Cell virt, Cell size, Int mode) { Translation *t; Translation *p = NULL; Translation *n; Retcode ret; if (size == 0) return NO_ERROR; ret = remove_translation(e, virt, size); if (ret != NO_ERROR) return ret; for (t = g_translations; t; p = t, t = t->next) if (virt < t->virt) break; t = (Translation *)malloc(sizeof (Translation)); if (t == NULL) return E_OUT_OF_MEMORY; t->virt = virt; t->phys = phys; t->size = size; t->mode = mode; if (p) { if (p->virt + p->size == virt && p->mode == mode && p->phys + p->size == phys) { /* merge p and t */ p->size += size; free(t); t = p; } else { t->next = p->next; p->next = t; } } else { t->next = g_translations; g_translations = t; } n = t->next; if (n && t->virt + t->size == n->virt && t->mode == n->mode && t->phys + t->size == n->phys) { /* merge t and n */ t->size += n->size; t->next = n->next; free(n); } return NO_ERROR; }