* vm_map_find finds an unallocated region in the target address * map with the given length. The search is defined to be * first-fit from the specified address; the region found is * returned in the same parameter. * * If object is non-NULL, ref count must be bumped by caller * prior to making call to account for the new entry. */
| 2121 | * prior to making call to account for the new entry. |
| 2122 | */ |
| 2123 | int |
| 2124 | vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset, |
| 2125 | vm_offset_t *addr, /* IN/OUT */ |
| 2126 | vm_size_t length, vm_offset_t max_addr, int find_space, |
| 2127 | vm_prot_t prot, vm_prot_t max, int cow) |
| 2128 | { |
| 2129 | vm_offset_t alignment, curr_min_addr, min_addr; |
| 2130 | int gap, pidx, rv, try; |
| 2131 | bool cluster, en_aslr, update_anon; |
| 2132 | |
| 2133 | KASSERT((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) == 0 || |
| 2134 | object == NULL, |
| 2135 | ("vm_map_find: non-NULL backing object for stack")); |
| 2136 | MPASS((cow & MAP_REMAP) == 0 || (find_space == VMFS_NO_SPACE && |
| 2137 | (cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) == 0)); |
| 2138 | if (find_space == VMFS_OPTIMAL_SPACE && (object == NULL || |
| 2139 | (object->flags & OBJ_COLORED) == 0)) |
| 2140 | find_space = VMFS_ANY_SPACE; |
| 2141 | if (find_space >> 8 != 0) { |
| 2142 | KASSERT((find_space & 0xff) == 0, ("bad VMFS flags")); |
| 2143 | alignment = (vm_offset_t)1 << (find_space >> 8); |
| 2144 | } else |
| 2145 | alignment = 0; |
| 2146 | en_aslr = (map->flags & MAP_ASLR) != 0; |
| 2147 | update_anon = cluster = clustering_anon_allowed(*addr) && |
| 2148 | (map->flags & MAP_IS_SUB_MAP) == 0 && max_addr == 0 && |
| 2149 | find_space != VMFS_NO_SPACE && object == NULL && |
| 2150 | (cow & (MAP_INHERIT_SHARE | MAP_STACK_GROWS_UP | |
| 2151 | MAP_STACK_GROWS_DOWN)) == 0 && prot != PROT_NONE; |
| 2152 | curr_min_addr = min_addr = *addr; |
| 2153 | if (en_aslr && min_addr == 0 && !cluster && |
| 2154 | find_space != VMFS_NO_SPACE && |
| 2155 | (map->flags & MAP_ASLR_IGNSTART) != 0) |
| 2156 | curr_min_addr = min_addr = vm_map_min(map); |
| 2157 | try = 0; |
| 2158 | vm_map_lock(map); |
| 2159 | if (cluster) { |
| 2160 | curr_min_addr = map->anon_loc; |
| 2161 | if (curr_min_addr == 0) |
| 2162 | cluster = false; |
| 2163 | } |
| 2164 | if (find_space != VMFS_NO_SPACE) { |
| 2165 | KASSERT(find_space == VMFS_ANY_SPACE || |
| 2166 | find_space == VMFS_OPTIMAL_SPACE || |
| 2167 | find_space == VMFS_SUPER_SPACE || |
| 2168 | alignment != 0, ("unexpected VMFS flag")); |
| 2169 | again: |
| 2170 | /* |
| 2171 | * When creating an anonymous mapping, try clustering |
| 2172 | * with an existing anonymous mapping first. |
| 2173 | * |
| 2174 | * We make up to two attempts to find address space |
| 2175 | * for a given find_space value. The first attempt may |
| 2176 | * apply randomization or may cluster with an existing |
| 2177 | * anonymous mapping. If this first attempt fails, |
| 2178 | * perform a first-fit search of the available address |
| 2179 | * space. |
| 2180 | * |
no test coverage detected