msync seems most well-defined test, but page could be mapped with * no permissions, and can't distiguish readonly from writable. */
| 266 | /* msync seems most well-defined test, but page could be mapped with |
| 267 | * no permissions, and can't distiguish readonly from writable. */ |
| 268 | bool ptr_valid_batch(struct ptr_valid_batch *batch, |
| 269 | const void *p, size_t alignment, size_t size, bool write) |
| 270 | { |
| 271 | char *start, *end; |
| 272 | bool ret; |
| 273 | |
| 274 | if ((intptr_t)p & (alignment - 1)) |
| 275 | return false; |
| 276 | |
| 277 | start = (void *)((intptr_t)p & ~(getpagesize() - 1)); |
| 278 | end = (void *)(((intptr_t)p + size - 1) & ~(getpagesize() - 1)); |
| 279 | |
| 280 | /* We cache single page hits. */ |
| 281 | if (start == end) { |
| 282 | if (batch->last && batch->last == start) |
| 283 | return batch->last_ok; |
| 284 | } |
| 285 | |
| 286 | if (batch->num_maps) |
| 287 | ret = check_with_maps(batch, p, size, write); |
| 288 | else |
| 289 | ret = check_with_child(batch, p, size, write); |
| 290 | |
| 291 | if (start == end) { |
| 292 | batch->last = start; |
| 293 | batch->last_ok = ret; |
| 294 | } |
| 295 | |
| 296 | return ret; |
| 297 | } |
| 298 | |
| 299 | bool ptr_valid_batch_string(struct ptr_valid_batch *batch, const char *p) |
| 300 | { |
no test coverage detected