1 /* 2 * Copyright (c) 2013-2019, 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_last_ip.h" 32 33 #include "intel-pt.h" 34 35 #include <string.h> 36 37 38 static struct ptunit_result init(void) 39 { 40 struct pt_last_ip last_ip; 41 42 memset(&last_ip, 0xcd, sizeof(last_ip)); 43 44 pt_last_ip_init(&last_ip); 45 46 ptu_uint_eq(last_ip.ip, 0ull); 47 ptu_uint_eq(last_ip.have_ip, 0); 48 ptu_uint_eq(last_ip.suppressed, 0); 49 50 return ptu_passed(); 51 } 52 53 static struct ptunit_result init_null(void) 54 { 55 pt_last_ip_init(NULL); 56 57 return ptu_passed(); 58 } 59 60 static struct ptunit_result status_initial(void) 61 { 62 struct pt_last_ip last_ip; 63 int errcode; 64 65 pt_last_ip_init(&last_ip); 66 67 errcode = pt_last_ip_query(NULL, &last_ip); 68 ptu_int_eq(errcode, -pte_noip); 69 70 return ptu_passed(); 71 } 72 73 static struct ptunit_result status(void) 74 { 75 struct pt_last_ip last_ip; 76 int errcode; 77 78 last_ip.have_ip = 1; 79 last_ip.suppressed = 0; 80 81 errcode = pt_last_ip_query(NULL, &last_ip); 82 ptu_int_eq(errcode, 0); 83 84 return ptu_passed(); 85 } 86 87 static struct ptunit_result status_null(void) 88 { 89 int errcode; 90 91 errcode = pt_last_ip_query(NULL, NULL); 92 ptu_int_eq(errcode, -pte_internal); 93 94 return ptu_passed(); 95 } 96 97 static struct ptunit_result status_noip(void) 98 { 99 struct pt_last_ip last_ip; 100 int errcode; 101 102 last_ip.have_ip = 0; 103 last_ip.suppressed = 0; 104 105 errcode = pt_last_ip_query(NULL, &last_ip); 106 ptu_int_eq(errcode, -pte_noip); 107 108 return ptu_passed(); 109 } 110 111 static struct ptunit_result status_suppressed(void) 112 { 113 struct pt_last_ip last_ip; 114 int errcode; 115 116 last_ip.have_ip = 1; 117 last_ip.suppressed = 1; 118 119 errcode = pt_last_ip_query(NULL, &last_ip); 120 ptu_int_eq(errcode, -pte_ip_suppressed); 121 122 return ptu_passed(); 123 } 124 125 static struct ptunit_result query_initial(void) 126 { 127 struct pt_last_ip last_ip; 128 uint64_t ip; 129 int errcode; 130 131 pt_last_ip_init(&last_ip); 132 133 errcode = pt_last_ip_query(&ip, &last_ip); 134 ptu_int_eq(errcode, -pte_noip); 135 136 return ptu_passed(); 137 } 138 139 static struct ptunit_result query(void) 140 { 141 struct pt_last_ip last_ip; 142 uint64_t ip, exp = 42ull; 143 int errcode; 144 145 last_ip.ip = 42ull; 146 last_ip.have_ip = 1; 147 last_ip.suppressed = 0; 148 149 errcode = pt_last_ip_query(&ip, &last_ip); 150 ptu_int_eq(errcode, 0); 151 ptu_uint_eq(last_ip.ip, exp); 152 153 return ptu_passed(); 154 } 155 156 static struct ptunit_result query_null(void) 157 { 158 uint64_t ip = 13ull; 159 int errcode; 160 161 errcode = pt_last_ip_query(&ip, NULL); 162 ptu_int_eq(errcode, -pte_internal); 163 ptu_uint_eq(ip, 13ull); 164 165 return ptu_passed(); 166 } 167 168 static struct ptunit_result query_noip(void) 169 { 170 struct pt_last_ip last_ip; 171 uint64_t ip = 13ull; 172 int errcode; 173 174 last_ip.ip = 42ull; 175 last_ip.have_ip = 0; 176 last_ip.suppressed = 0; 177 178 errcode = pt_last_ip_query(&ip, &last_ip); 179 ptu_int_eq(errcode, -pte_noip); 180 ptu_uint_eq(ip, 0ull); 181 182 return ptu_passed(); 183 } 184 185 static struct ptunit_result query_suppressed(void) 186 { 187 struct pt_last_ip last_ip; 188 uint64_t ip = 13ull; 189 int errcode; 190 191 last_ip.ip = 42ull; 192 last_ip.have_ip = 1; 193 last_ip.suppressed = 1; 194 195 errcode = pt_last_ip_query(&ip, &last_ip); 196 ptu_int_eq(errcode, -pte_ip_suppressed); 197 ptu_uint_eq(ip, 0ull); 198 199 return ptu_passed(); 200 } 201 202 static struct ptunit_result update_ip_suppressed(uint32_t have_ip) 203 { 204 struct pt_last_ip last_ip; 205 struct pt_packet_ip packet; 206 int errcode; 207 208 last_ip.ip = 42ull; 209 last_ip.have_ip = have_ip; 210 last_ip.suppressed = 0; 211 212 packet.ipc = pt_ipc_suppressed; 213 packet.ip = 13ull; 214 215 errcode = pt_last_ip_update_ip(&last_ip, &packet, NULL); 216 ptu_int_eq(errcode, 0); 217 ptu_uint_eq(last_ip.ip, 42ull); 218 ptu_uint_eq(last_ip.have_ip, have_ip); 219 ptu_uint_eq(last_ip.suppressed, 1); 220 221 return ptu_passed(); 222 } 223 224 static struct ptunit_result update_ip_upd16(uint32_t have_ip) 225 { 226 struct pt_last_ip last_ip; 227 struct pt_packet_ip packet; 228 int errcode; 229 230 last_ip.ip = 0xff0042ull; 231 last_ip.have_ip = have_ip; 232 last_ip.suppressed = 0; 233 234 packet.ipc = pt_ipc_update_16; 235 packet.ip = 0xccc013ull; 236 237 errcode = pt_last_ip_update_ip(&last_ip, &packet, NULL); 238 ptu_int_eq(errcode, 0); 239 ptu_uint_eq(last_ip.ip, 0xffc013ull); 240 ptu_uint_eq(last_ip.have_ip, 1); 241 ptu_uint_eq(last_ip.suppressed, 0); 242 243 return ptu_passed(); 244 } 245 246 static struct ptunit_result update_ip_upd32(uint32_t have_ip) 247 { 248 struct pt_last_ip last_ip; 249 struct pt_packet_ip packet; 250 int errcode; 251 252 last_ip.ip = 0xff00000420ull; 253 last_ip.have_ip = have_ip; 254 last_ip.suppressed = 0; 255 256 packet.ipc = pt_ipc_update_32; 257 packet.ip = 0xcc0000c013ull; 258 259 errcode = pt_last_ip_update_ip(&last_ip, &packet, NULL); 260 ptu_int_eq(errcode, 0); 261 ptu_uint_eq(last_ip.ip, 0xff0000c013ull); 262 ptu_uint_eq(last_ip.have_ip, 1); 263 ptu_uint_eq(last_ip.suppressed, 0); 264 265 return ptu_passed(); 266 } 267 268 static struct ptunit_result update_ip_sext48(uint32_t have_ip) 269 { 270 struct pt_last_ip last_ip; 271 struct pt_packet_ip packet; 272 int errcode; 273 274 last_ip.ip = 0x7fffffffffffffffull; 275 last_ip.have_ip = have_ip; 276 last_ip.suppressed = 0; 277 278 packet.ipc = pt_ipc_sext_48; 279 packet.ip = 0xff00000000ffull; 280 281 errcode = pt_last_ip_update_ip(&last_ip, &packet, NULL); 282 ptu_int_eq(errcode, 0); 283 ptu_uint_eq(last_ip.ip, 0xffffff00000000ffull); 284 ptu_uint_eq(last_ip.have_ip, 1); 285 ptu_uint_eq(last_ip.suppressed, 0); 286 287 return ptu_passed(); 288 } 289 290 static struct ptunit_result update_ip_bad_packet(uint32_t have_ip) 291 { 292 struct pt_last_ip last_ip; 293 struct pt_packet_ip packet; 294 int errcode; 295 296 last_ip.ip = 0x7fffffffffffffffull; 297 last_ip.have_ip = have_ip; 298 last_ip.suppressed = 0; 299 300 packet.ipc = (enum pt_ip_compression) 0xff; 301 packet.ip = 0ull; 302 303 errcode = pt_last_ip_update_ip(&last_ip, &packet, NULL); 304 ptu_int_eq(errcode, -pte_bad_packet); 305 ptu_uint_eq(last_ip.ip, 0x7fffffffffffffffull); 306 ptu_uint_eq(last_ip.have_ip, have_ip); 307 ptu_uint_eq(last_ip.suppressed, 0); 308 309 return ptu_passed(); 310 } 311 312 static struct ptunit_result update_ip_null_ip(void) 313 { 314 struct pt_packet_ip packet; 315 int errcode; 316 317 errcode = pt_last_ip_update_ip(NULL, &packet, NULL); 318 ptu_int_eq(errcode, -pte_internal); 319 320 return ptu_passed(); 321 } 322 323 static struct ptunit_result update_ip_null_packet(uint32_t have_ip) 324 { 325 struct pt_last_ip last_ip; 326 int errcode; 327 328 last_ip.ip = 0x7fffffffffffffffull; 329 last_ip.have_ip = have_ip; 330 last_ip.suppressed = 0; 331 332 errcode = pt_last_ip_update_ip(&last_ip, NULL, NULL); 333 ptu_int_eq(errcode, -pte_internal); 334 ptu_uint_eq(last_ip.ip, 0x7fffffffffffffffull); 335 ptu_uint_eq(last_ip.have_ip, have_ip); 336 ptu_uint_eq(last_ip.suppressed, 0); 337 338 return ptu_passed(); 339 } 340 341 int main(int argc, char **argv) 342 { 343 struct ptunit_suite suite; 344 345 suite = ptunit_mk_suite(argc, argv); 346 347 ptu_run(suite, init); 348 ptu_run(suite, init_null); 349 ptu_run(suite, status_initial); 350 ptu_run(suite, status); 351 ptu_run(suite, status_null); 352 ptu_run(suite, status_noip); 353 ptu_run(suite, status_suppressed); 354 ptu_run(suite, query_initial); 355 ptu_run(suite, query); 356 ptu_run(suite, query_null); 357 ptu_run(suite, query_noip); 358 ptu_run(suite, query_suppressed); 359 ptu_run_p(suite, update_ip_suppressed, 0); 360 ptu_run_p(suite, update_ip_suppressed, 1); 361 ptu_run_p(suite, update_ip_upd16, 0); 362 ptu_run_p(suite, update_ip_upd16, 1); 363 ptu_run_p(suite, update_ip_upd32, 0); 364 ptu_run_p(suite, update_ip_upd32, 1); 365 ptu_run_p(suite, update_ip_sext48, 0); 366 ptu_run_p(suite, update_ip_sext48, 1); 367 ptu_run_p(suite, update_ip_bad_packet, 0); 368 ptu_run_p(suite, update_ip_bad_packet, 1); 369 ptu_run(suite, update_ip_null_ip); 370 ptu_run_p(suite, update_ip_null_packet, 0); 371 ptu_run_p(suite, update_ip_null_packet, 1); 372 373 return ptunit_report(&suite); 374 } 375