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