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