- char *lo = NULL; /* beginning of current range in maps file */
- char *hi = NULL; /* end of current range in maps file */
- char *raddr = minaddr; /* ignore regions below 'minaddr' */
-
-#ifdef WIN32
- MEMORY_BASIC_INFORMATION mi;
-#else
- FILE *fp;
- char line[PROCMAXLEN]; /* for fgets() */
-#endif
-
- dprint(FD_IO, "DEBUG util_map_hint_unused\n");
- assert(align > 0);
-
- if (raddr == NULL)
- raddr += page_size;
-
- raddr = (char *)roundup((uintptr_t)raddr, align);
-
-#ifdef WIN32
- while ((uintptr_t)raddr < UINTPTR_MAX - len) {
- size_t ret = VirtualQuery(raddr, &mi, sizeof(mi));
- if (ret == 0) {
- ERR("VirtualQuery %p", raddr);
- return MAP_FAILED;
- }
- dprint(FD_IO, "addr %p len %zu state %d",
- mi.BaseAddress, mi.RegionSize, mi.State);
-
- if ((mi.State != MEM_FREE) || (mi.RegionSize < len)) {
- raddr = (char *)mi.BaseAddress + mi.RegionSize;
- raddr = (char *)roundup((uintptr_t)raddr, align);
- dprint(FD_IO, "nearest aligned addr %p", raddr);
- } else {
- dprint(FD_IO, "unused region of size %zu found at %p",
- mi.RegionSize, mi.BaseAddress);
- return mi.BaseAddress;
- }
- }
-
- dprint(FD_IO, "end of address space reached");
- return MAP_FAILED;
-#else
- fp = fopen(OS_MAPFILE, "r");
- if (!fp) {
- log_err("!%s\n", OS_MAPFILE);
- return MAP_FAILED;
- }
-
- while (fgets(line, PROCMAXLEN, fp) != NULL) {
- /* check for range line */
- if (sscanf(line, sscanf_os, &lo, &hi) == 2) {
- dprint(FD_IO, "%p-%p\n", lo, hi);
- if (lo > raddr) {
- if ((uintptr_t)(lo - raddr) >= len) {
- dprint(FD_IO, "unused region of size "
- "%zu found at %p\n",
- lo - raddr, raddr);
- break;
- } else {
- dprint(FD_IO, "region is too small: "
- "%zu < %zu\n",
- lo - raddr, len);
- }
- }
-
- if (hi > raddr) {
- raddr = (char *)roundup((uintptr_t)hi, align);
- dprint(FD_IO, "nearest aligned addr %p\n",
- raddr);
- }
-
- if (raddr == 0) {
- dprint(FD_IO, "end of address space reached\n");
- break;
- }
- }
- }
-
- /*
- * Check for a case when this is the last unused range in the address
- * space, but is not large enough. (very unlikely)
- */
- if ((raddr != NULL) && (UINTPTR_MAX - (uintptr_t)raddr < len)) {
- dprint(FD_IO, "end of address space reached");
- raddr = MAP_FAILED;
- }
-
- fclose(fp);
-
- dprint(FD_IO, "returning %p", raddr);
- return raddr;
-#endif
-}