Esempio n. 1
0
static uintptr_t
ReservePoisonArea()
{
  if (sizeof(uintptr_t) == 8) {
    // Use the hardware-inaccessible region.
    // We have to avoid 64-bit constants and shifts by 32 bits, since this
    // code is compiled in 32-bit mode, although it is never executed there.
    uintptr_t result = (((uintptr_t(0x7FFFFFFFu) << 31) << 1 |
                         uintptr_t(0xF0DEAFFFu)) &
                        ~uintptr_t(PageSize()-1));
    printf("INFO | poison area assumed at 0x%.*" PRIxPTR "\n", SIZxPTR, result);
    return result;
  }

  // First see if we can allocate the preferred poison address from the OS.
  uintptr_t candidate = (0xF0DEAFFF & ~(PageSize() - 1));
  void* result = ReserveRegion(candidate, false);
  if (result == reinterpret_cast<void*>(candidate)) {
    // success - inaccessible page allocated
    printf("INFO | poison area allocated at 0x%.*" PRIxPTR
           " (preferred addr)\n", SIZxPTR, reinterpret_cast<uintptr_t>(result));
    return candidate;
  }

  // That didn't work, so see if the preferred address is within a range
  // of permanently inacessible memory.
  if (ProbeRegion(candidate)) {
    // success - selected page cannot be usable memory
    if (result != MAP_FAILED) {
      ReleaseRegion(result);
    }
    printf("INFO | poison area assumed at 0x%.*" PRIxPTR
           " (preferred addr)\n", SIZxPTR, candidate);
    return candidate;
  }

  // The preferred address is already in use.  Did the OS give us a
  // consolation prize?
  if (result != MAP_FAILED) {
    uintptr_t ures = reinterpret_cast<uintptr_t>(result);
    printf("INFO | poison area allocated at 0x%.*" PRIxPTR
           " (consolation prize)\n", SIZxPTR, ures);
    return ures;
  }

  // It didn't, so try to allocate again, without any constraint on
  // the address.
  result = ReserveRegion(0, false);
  if (result != MAP_FAILED) {
    uintptr_t ures = reinterpret_cast<uintptr_t>(result);
    printf("INFO | poison area allocated at 0x%.*" PRIxPTR
           " (fallback)\n", SIZxPTR, ures);
    return ures;
  }

  printf("ERROR | no usable poison area found\n");
  return 0;
}
Esempio n. 2
0
static PRUword
ReservePoisonArea(PRUword rgnsize)
{
  if (sizeof(PRUword) == 8) {
    // Use the hardware-inaccessible region.
    // We have to avoid 64-bit constants and shifts by 32 bits, since this
    // code is compiled in 32-bit mode, although it is never executed there.
    return
      (((PRUword(0x7FFFFFFFu) << 31) << 1 | PRUword(0xF0DEAFFFu))
       & ~(rgnsize-1));

  } else {
    // First see if we can allocate the preferred poison address from the OS.
    PRUword candidate = (0xF0DEAFFF & ~(rgnsize-1));
    void *result = ReserveRegion(candidate, rgnsize);
    if (result == (void *)candidate) {
      // success - inaccessible page allocated
      return candidate;
    }

    // That didn't work, so see if the preferred address is within a range
    // of permanently inacessible memory.
    if (ProbeRegion(candidate, rgnsize)) {
      // success - selected page cannot be usable memory
      if (result != RESERVE_FAILED)
        ReleaseRegion(result, rgnsize);
      return candidate;
    }

    // The preferred address is already in use.  Did the OS give us a
    // consolation prize?
    if (result != RESERVE_FAILED) {
      return PRUword(result);
    }

    // It didn't, so try to allocate again, without any constraint on
    // the address.
    result = ReserveRegion(0, rgnsize);
    if (result != RESERVE_FAILED) {
      return PRUword(result);
    }

    NS_RUNTIMEABORT("no usable poison region identified");
    return 0;
  }
}