void *autodata_make_table(const void *example, const char *name, size_t *nump) { const char *start, *end, *tag; struct ptr_valid_batch batch; const void *const magic = (void *)AUTODATA_MAGIC; void **table = NULL; char first_magic; if (!ptr_valid_batch_start(&batch)) return NULL; /* Get range to search. */ for (start = (char *)((intptr_t)example & ~(getpagesize() - 1)); ptr_valid_batch(&batch, start-getpagesize(), 1, sizeof(void *), false); start -= getpagesize()); for (end = (char *)((intptr_t)example & ~(getpagesize() - 1)); ptr_valid_batch(&batch, end, 1, sizeof(void *), false); end += getpagesize()); *nump = 0; first_magic = *(char *)&magic; for (tag = memchr(start, first_magic, end - start); tag; tag = memchr(tag+1, first_magic, end - (tag + 1))) { void *adata[4]; /* We can read 4 void *'s here? */ if (tag + sizeof(adata) > end) continue; memcpy(adata, tag, sizeof(adata)); /* False match? */ if (adata[0] != (void *)AUTODATA_MAGIC || adata[1] != tag) continue; /* OK, check name. */ if (!ptr_valid_batch_string(&batch, adata[3]) || strcmp(name, adata[3]) != 0) continue; if (!ptr_valid_batch_read(&batch, (char *)adata[2])) continue; table = realloc(table, sizeof(void *) * (*nump + 1)); if (!table) break; table[*nump] = adata[2]; (*nump)++; } ptr_valid_batch_end(&batch); return table; }
bool ptr_valid_batch_string(struct ptr_valid_batch *batch, const char *p) { while (ptr_valid_batch(batch, p, 1, 1, false)) { if (*p == '\0') return true; p++; } return false; }
bool ptr_valid(const void *p, size_t alignment, size_t size, bool write) { bool ret; struct ptr_valid_batch batch; if (!ptr_valid_batch_start(&batch)) return false; ret = ptr_valid_batch(&batch, p, alignment, size, write); ptr_valid_batch_end(&batch); return ret; }