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