1 /* 2 * Copyright (c) 2014-2018, Intel Corporation 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * * Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * * Neither the name of Intel Corporation nor the names of its contributors 13 * may be used to endorse or promote products derived from this software 14 * without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "ptunit.h" 30 31 #include "pt_sync.h" 32 #include "pt_opcodes.h" 33 34 #include "intel-pt.h" 35 36 37 /* A test fixture for sync tests. */ 38 struct sync_fixture { 39 /* The trace buffer. */ 40 uint8_t buffer[1024]; 41 42 /* A trace configuration. */ 43 struct pt_config config; 44 45 /* The test fixture initialization and finalization functions. */ 46 struct ptunit_result (*init)(struct sync_fixture *); 47 struct ptunit_result (*fini)(struct sync_fixture *); 48 }; 49 50 static struct ptunit_result sfix_init(struct sync_fixture *sfix) 51 { 52 memset(sfix->buffer, 0xcd, sizeof(sfix->buffer)); 53 54 memset(&sfix->config, 0, sizeof(sfix->config)); 55 sfix->config.size = sizeof(sfix->config); 56 sfix->config.begin = sfix->buffer; 57 sfix->config.end = sfix->buffer + sizeof(sfix->buffer); 58 59 return ptu_passed(); 60 } 61 62 static void sfix_encode_psb(uint8_t *pos) 63 { 64 int i; 65 66 *pos++ = pt_opc_psb; 67 *pos++ = pt_ext_psb; 68 69 for (i = 0; i < pt_psb_repeat_count; ++i) { 70 *pos++ = pt_psb_hi; 71 *pos++ = pt_psb_lo; 72 } 73 } 74 75 76 static struct ptunit_result sync_fwd_null(struct sync_fixture *sfix) 77 { 78 const uint8_t *sync; 79 int errcode; 80 81 errcode = pt_sync_forward(NULL, sfix->config.begin, &sfix->config); 82 ptu_int_eq(errcode, -pte_internal); 83 84 errcode = pt_sync_forward(&sync, NULL, &sfix->config); 85 ptu_int_eq(errcode, -pte_internal); 86 87 errcode = pt_sync_forward(&sync, sfix->config.begin, NULL); 88 ptu_int_eq(errcode, -pte_internal); 89 90 return ptu_passed(); 91 } 92 93 static struct ptunit_result sync_bwd_null(struct sync_fixture *sfix) 94 { 95 const uint8_t *sync; 96 int errcode; 97 98 errcode = pt_sync_backward(NULL, sfix->config.begin, &sfix->config); 99 ptu_int_eq(errcode, -pte_internal); 100 101 errcode = pt_sync_backward(&sync, NULL, &sfix->config); 102 ptu_int_eq(errcode, -pte_internal); 103 104 errcode = pt_sync_backward(&sync, sfix->config.begin, NULL); 105 ptu_int_eq(errcode, -pte_internal); 106 107 return ptu_passed(); 108 } 109 110 static struct ptunit_result sync_fwd_empty(struct sync_fixture *sfix) 111 { 112 const uint8_t *sync; 113 int errcode; 114 115 sfix->config.end = sfix->config.begin; 116 117 errcode = pt_sync_forward(&sync, sfix->config.begin, &sfix->config); 118 ptu_int_eq(errcode, -pte_eos); 119 120 return ptu_passed(); 121 } 122 123 static struct ptunit_result sync_bwd_empty(struct sync_fixture *sfix) 124 { 125 const uint8_t *sync; 126 int errcode; 127 128 sfix->config.end = sfix->config.begin; 129 130 errcode = pt_sync_backward(&sync, sfix->config.end, &sfix->config); 131 ptu_int_eq(errcode, -pte_eos); 132 133 return ptu_passed(); 134 } 135 136 static struct ptunit_result sync_fwd_none(struct sync_fixture *sfix) 137 { 138 const uint8_t *sync; 139 int errcode; 140 141 errcode = pt_sync_forward(&sync, sfix->config.begin, &sfix->config); 142 ptu_int_eq(errcode, -pte_eos); 143 144 return ptu_passed(); 145 } 146 147 static struct ptunit_result sync_bwd_none(struct sync_fixture *sfix) 148 { 149 const uint8_t *sync; 150 int errcode; 151 152 errcode = pt_sync_backward(&sync, sfix->config.end, &sfix->config); 153 ptu_int_eq(errcode, -pte_eos); 154 155 return ptu_passed(); 156 } 157 158 static struct ptunit_result sync_fwd_here(struct sync_fixture *sfix) 159 { 160 const uint8_t *sync; 161 int errcode; 162 163 sfix_encode_psb(sfix->config.begin); 164 165 errcode = pt_sync_forward(&sync, sfix->config.begin, &sfix->config); 166 ptu_int_eq(errcode, 0); 167 ptu_ptr_eq(sync, sfix->config.begin); 168 169 return ptu_passed(); 170 } 171 172 static struct ptunit_result sync_bwd_here(struct sync_fixture *sfix) 173 { 174 const uint8_t *sync; 175 int errcode; 176 177 sfix_encode_psb(sfix->config.end - ptps_psb); 178 179 errcode = pt_sync_backward(&sync, sfix->config.end, &sfix->config); 180 ptu_int_eq(errcode, 0); 181 ptu_ptr_eq(sync, sfix->config.end - ptps_psb); 182 183 return ptu_passed(); 184 } 185 186 static struct ptunit_result sync_fwd(struct sync_fixture *sfix) 187 { 188 const uint8_t *sync; 189 int errcode; 190 191 sfix_encode_psb(sfix->config.begin + 0x23); 192 193 errcode = pt_sync_forward(&sync, sfix->config.begin, &sfix->config); 194 ptu_int_eq(errcode, 0); 195 ptu_ptr_eq(sync, sfix->config.begin + 0x23); 196 197 return ptu_passed(); 198 } 199 200 static struct ptunit_result sync_bwd(struct sync_fixture *sfix) 201 { 202 const uint8_t *sync; 203 int errcode; 204 205 sfix_encode_psb(sfix->config.begin + 0x23); 206 207 errcode = pt_sync_backward(&sync, sfix->config.end, &sfix->config); 208 ptu_int_eq(errcode, 0); 209 ptu_ptr_eq(sync, sfix->config.begin + 0x23); 210 211 return ptu_passed(); 212 } 213 214 static struct ptunit_result sync_fwd_past(struct sync_fixture *sfix) 215 { 216 const uint8_t *sync; 217 int errcode; 218 219 sfix_encode_psb(sfix->config.begin); 220 221 errcode = pt_sync_forward(&sync, sfix->config.begin + ptps_psb, 222 &sfix->config); 223 ptu_int_eq(errcode, -pte_eos); 224 225 return ptu_passed(); 226 } 227 228 static struct ptunit_result sync_bwd_past(struct sync_fixture *sfix) 229 { 230 const uint8_t *sync; 231 int errcode; 232 233 sfix_encode_psb(sfix->config.end - ptps_psb); 234 235 errcode = pt_sync_backward(&sync, sfix->config.end - ptps_psb, 236 &sfix->config); 237 ptu_int_eq(errcode, -pte_eos); 238 239 return ptu_passed(); 240 } 241 242 static struct ptunit_result sync_fwd_cutoff(struct sync_fixture *sfix) 243 { 244 const uint8_t *sync; 245 int errcode; 246 247 sfix_encode_psb(sfix->config.begin); 248 sfix_encode_psb(sfix->config.end - ptps_psb); 249 sfix->config.begin += 1; 250 sfix->config.end -= 1; 251 252 errcode = pt_sync_forward(&sync, sfix->config.begin, &sfix->config); 253 ptu_int_eq(errcode, -pte_eos); 254 255 return ptu_passed(); 256 } 257 258 static struct ptunit_result sync_bwd_cutoff(struct sync_fixture *sfix) 259 { 260 const uint8_t *sync; 261 int errcode; 262 263 sfix_encode_psb(sfix->config.begin); 264 sfix_encode_psb(sfix->config.end - ptps_psb); 265 sfix->config.begin += 1; 266 sfix->config.end -= 1; 267 268 errcode = pt_sync_backward(&sync, sfix->config.end, &sfix->config); 269 ptu_int_eq(errcode, -pte_eos); 270 271 return ptu_passed(); 272 } 273 274 int main(int argc, char **argv) 275 { 276 struct sync_fixture sfix; 277 struct ptunit_suite suite; 278 279 sfix.init = sfix_init; 280 sfix.fini = NULL; 281 282 suite = ptunit_mk_suite(argc, argv); 283 284 ptu_run_f(suite, sync_fwd_null, sfix); 285 ptu_run_f(suite, sync_bwd_null, sfix); 286 287 ptu_run_f(suite, sync_fwd_empty, sfix); 288 ptu_run_f(suite, sync_bwd_empty, sfix); 289 290 ptu_run_f(suite, sync_fwd_none, sfix); 291 ptu_run_f(suite, sync_bwd_none, sfix); 292 293 ptu_run_f(suite, sync_fwd_here, sfix); 294 ptu_run_f(suite, sync_bwd_here, sfix); 295 296 ptu_run_f(suite, sync_fwd, sfix); 297 ptu_run_f(suite, sync_bwd, sfix); 298 299 ptu_run_f(suite, sync_fwd_past, sfix); 300 ptu_run_f(suite, sync_bwd_past, sfix); 301 302 ptu_run_f(suite, sync_fwd_cutoff, sfix); 303 ptu_run_f(suite, sync_bwd_cutoff, sfix); 304 305 return ptunit_report(&suite); 306 } 307