1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
// Licensed under BSD-MIT: See LICENSE.
#include "autodata.h"
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#if HAVE_SECTION_START_STOP
void *autodata_get_section(void *start, void *stop, size_t *nump)
{
*nump = (void **)(stop) - (void **)(start);
return start;
}
void autodata_free(void *table)
{
}
#else
#include <ccan/ptr_valid/ptr_valid.h>
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;
}
void autodata_free(void *table)
{
free(table);
}
#endif
|