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