1 #include "util.h"
2 
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <string.h>
8 
9 #include "machine.h"
10 #include "symbol.h"
11 #include "tests.h"
12 
test_file(int size)13 static char *test_file(int size)
14 {
15 	static char buf_templ[] = "/tmp/test-XXXXXX";
16 	char *templ = buf_templ;
17 	int fd, i;
18 	unsigned char *buf;
19 
20 	fd = mkstemp(templ);
21 	if (fd < 0) {
22 		perror("mkstemp failed");
23 		return NULL;
24 	}
25 
26 	buf = malloc(size);
27 	if (!buf) {
28 		close(fd);
29 		return NULL;
30 	}
31 
32 	for (i = 0; i < size; i++)
33 		buf[i] = (unsigned char) ((int) i % 10);
34 
35 	if (size != write(fd, buf, size))
36 		templ = NULL;
37 
38 	close(fd);
39 	return templ;
40 }
41 
42 #define TEST_FILE_SIZE (DSO__DATA_CACHE_SIZE * 20)
43 
44 struct test_data_offset {
45 	off_t offset;
46 	u8 data[10];
47 	int size;
48 };
49 
50 struct test_data_offset offsets[] = {
51 	/* Fill first cache page. */
52 	{
53 		.offset = 10,
54 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
55 		.size   = 10,
56 	},
57 	/* Read first cache page. */
58 	{
59 		.offset = 10,
60 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
61 		.size   = 10,
62 	},
63 	/* Fill cache boundary pages. */
64 	{
65 		.offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10,
66 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
67 		.size   = 10,
68 	},
69 	/* Read cache boundary pages. */
70 	{
71 		.offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10,
72 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
73 		.size   = 10,
74 	},
75 	/* Fill final cache page. */
76 	{
77 		.offset = TEST_FILE_SIZE - 10,
78 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
79 		.size   = 10,
80 	},
81 	/* Read final cache page. */
82 	{
83 		.offset = TEST_FILE_SIZE - 10,
84 		.data   = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
85 		.size   = 10,
86 	},
87 	/* Read final cache page. */
88 	{
89 		.offset = TEST_FILE_SIZE - 3,
90 		.data   = { 7, 8, 9, 0, 0, 0, 0, 0, 0, 0 },
91 		.size   = 3,
92 	},
93 };
94 
test__dso_data(void)95 int test__dso_data(void)
96 {
97 	struct machine machine;
98 	struct dso *dso;
99 	char *file = test_file(TEST_FILE_SIZE);
100 	size_t i;
101 
102 	TEST_ASSERT_VAL("No test file", file);
103 
104 	memset(&machine, 0, sizeof(machine));
105 
106 	dso = dso__new((const char *)file);
107 
108 	/* Basic 10 bytes tests. */
109 	for (i = 0; i < ARRAY_SIZE(offsets); i++) {
110 		struct test_data_offset *data = &offsets[i];
111 		ssize_t size;
112 		u8 buf[10];
113 
114 		memset(buf, 0, 10);
115 		size = dso__data_read_offset(dso, &machine, data->offset,
116 				     buf, 10);
117 
118 		TEST_ASSERT_VAL("Wrong size", size == data->size);
119 		TEST_ASSERT_VAL("Wrong data", !memcmp(buf, data->data, 10));
120 	}
121 
122 	/* Read cross multiple cache pages. */
123 	{
124 		ssize_t size;
125 		int c;
126 		u8 *buf;
127 
128 		buf = malloc(TEST_FILE_SIZE);
129 		TEST_ASSERT_VAL("ENOMEM\n", buf);
130 
131 		/* First iteration to fill caches, second one to read them. */
132 		for (c = 0; c < 2; c++) {
133 			memset(buf, 0, TEST_FILE_SIZE);
134 			size = dso__data_read_offset(dso, &machine, 10,
135 						     buf, TEST_FILE_SIZE);
136 
137 			TEST_ASSERT_VAL("Wrong size",
138 				size == (TEST_FILE_SIZE - 10));
139 
140 			for (i = 0; i < (size_t)size; i++)
141 				TEST_ASSERT_VAL("Wrong data",
142 					buf[i] == (i % 10));
143 		}
144 
145 		free(buf);
146 	}
147 
148 	dso__delete(dso);
149 	unlink(file);
150 	return 0;
151 }
152