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 38static 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 53static struct ptunit_result init_null(void) 54{ 55 pt_last_ip_init(NULL); 56 57 return ptu_passed(); 58} 59 60static 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 73static 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 87static 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 97static 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 111static 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 125static 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 139static 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 156static 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 168static 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 185static 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 202static 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 224static 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 246static 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 268static 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 290static 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 312static 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 323static 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 341int 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