Exemple #1
0
void NaClVmmapMakeSorted(struct NaClVmmap  *self) {
  if (self->is_sorted)
    return;

  NaClVmmapRemoveMarked(self);

  qsort(self->vmentry,
        self->nvalid,
        sizeof *self->vmentry,
        NaClVmmapCmpEntries);
  self->is_sorted = 1;
#if REMOVE_MARKED_DEBUG
  NaClVmmapDebug(self, "After Sort");
#endif
}
Exemple #2
0
/*
 * Update the virtual memory map.  Deletion is handled by a remove
 * flag, since a NULL nmop just means that the memory is backed by the
 * system paging file.
 */
void NaClVmmapUpdate(struct NaClVmmap   *self,
                     uintptr_t          page_num,
                     size_t             npages,
                     int                prot,
                     struct NaClMemObj  *nmop,
                     int                remove) {
  /* update existing entries or create new entry as needed */
  size_t                i;
  uintptr_t             new_region_end_page = page_num + npages;

  NaClLog(2,
          ("NaClVmmapUpdate(0x%08"NACL_PRIxPTR", "
           "0x%"NACL_PRIxPTR", 0x%"NACL_PRIxS", "
           "0x%x, 0x%08"NACL_PRIxPTR", %d)\n"),
          (uintptr_t) self, page_num, npages, prot, (uintptr_t) nmop,
          remove);
  NaClVmmapMakeSorted(self);

  CHECK(npages > 0);

  for (i = 0; i < self->nvalid; i++) {
    struct NaClVmmapEntry *ent = self->vmentry[i];
    uintptr_t             ent_end_page = ent->page_num + ent->npages;
    nacl_off64_t          additional_offset =
        (new_region_end_page - ent->page_num) << NACL_PAGESHIFT;

    if (ent->page_num < page_num && new_region_end_page < ent_end_page) {
      /*
       * Split existing mapping into two parts, with new mapping in
       * the middle.
       */
      if (!NaClVmmapAdd(self,
                        new_region_end_page,
                        ent_end_page - new_region_end_page,
                        ent->prot,
                        NaClMemObjSplit(ent->nmop, additional_offset))) {
        NaClLog(LOG_FATAL, "NaClVmmapUpdate: could not split entry\n");
      }
      ent->npages = page_num - ent->page_num;
      break;
    } else if (ent->page_num < page_num && page_num < ent_end_page) {
      /* New mapping overlaps end of existing mapping. */
      ent->npages = page_num - ent->page_num;
    } else if (ent->page_num < new_region_end_page &&
               new_region_end_page < ent_end_page) {
      /* New mapping overlaps start of existing mapping. */

      NaClMemObjIncOffset(ent->nmop, additional_offset);

      ent->page_num = new_region_end_page;
      ent->npages = ent_end_page - new_region_end_page;
      break;
    } else if (page_num <= ent->page_num &&
               ent_end_page <= new_region_end_page) {
      /* New mapping covers all of the existing mapping. */
      ent->removed = 1;
    } else {
      /* No overlap */
      assert(new_region_end_page <= ent->page_num || ent_end_page <= page_num);
    }
  }

  if (!remove) {
    if (!NaClVmmapAdd(self, page_num, npages, prot, nmop)) {
      NaClLog(LOG_FATAL, "NaClVmmapUpdate: could not add entry\n");
    }
  }

  NaClVmmapRemoveMarked(self);
}
Exemple #3
0
/*
 * Update the virtual memory map.  Deletion is handled by a remove
 * flag, since a NULL desc just means that the memory is backed by the
 * system paging file.
 */
static void NaClVmmapUpdate(struct NaClVmmap  *self,
                            uintptr_t         page_num,
                            size_t            npages,
                            int               prot,
                            int               flags,
                            int               remove,
                            struct NaClDesc   *desc,
                            nacl_off64_t      offset,
                            nacl_off64_t      file_size) {
  /* update existing entries or create new entry as needed */
  size_t                i;
  uintptr_t             new_region_end_page = page_num + npages;

  NaClLog(2,
          ("NaClVmmapUpdate(0x%08"NACL_PRIxPTR", 0x%"NACL_PRIxPTR", "
           "0x%"NACL_PRIxS", 0x%x, 0x%x, %d, 0x%"NACL_PRIxPTR", "
           "0x%"NACL_PRIx64")\n"),
          (uintptr_t) self, page_num, npages, prot, flags,
          remove, (uintptr_t) desc, offset);
  NaClVmmapMakeSorted(self);

  CHECK(npages > 0);

  for (i = 0; i < self->nvalid; i++) {
    struct NaClVmmapEntry *ent = self->vmentry[i];
    uintptr_t             ent_end_page = ent->page_num + ent->npages;
    nacl_off64_t          additional_offset =
        (new_region_end_page - ent->page_num) << NACL_PAGESHIFT;


    if (ent->page_num < page_num && new_region_end_page < ent_end_page) {
      /*
       * Split existing mapping into two parts, with new mapping in
       * the middle.
       */
      NaClVmmapAdd(self,
                   new_region_end_page,
                   ent_end_page - new_region_end_page,
                   ent->prot,
                   ent->flags,
                   ent->desc,
                   ent->offset + additional_offset,
                   ent->file_size);
      ent->npages = page_num - ent->page_num;
      break;
    } else if (ent->page_num < page_num && page_num < ent_end_page) {
      /* New mapping overlaps end of existing mapping. */
      ent->npages = page_num - ent->page_num;
    } else if (ent->page_num < new_region_end_page &&
               new_region_end_page < ent_end_page) {
      /* New mapping overlaps start of existing mapping. */
      ent->page_num = new_region_end_page;
      ent->npages = ent_end_page - new_region_end_page;
      ent->offset += additional_offset;
      break;
    } else if (page_num <= ent->page_num &&
               ent_end_page <= new_region_end_page) {
      /* New mapping covers all of the existing mapping. */
      ent->removed = 1;
    } else {
      /* No overlap */
      assert(new_region_end_page <= ent->page_num || ent_end_page <= page_num);
    }
  }

  if (!remove) {
    NaClVmmapAdd(self, page_num, npages, prot, flags, desc, offset, file_size);
  }

  NaClVmmapRemoveMarked(self);
}