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