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_retstack.h" 32 33 #include "intel-pt.h" 34 35 36 static struct ptunit_result init(void) 37 { 38 struct pt_retstack retstack; 39 int status; 40 41 memset(&retstack, 0xcd, sizeof(retstack)); 42 43 pt_retstack_init(&retstack); 44 45 status = pt_retstack_is_empty(&retstack); 46 ptu_int_ne(status, 0); 47 48 return ptu_passed(); 49 } 50 51 static struct ptunit_result init_null(void) 52 { 53 pt_retstack_init(NULL); 54 55 return ptu_passed(); 56 } 57 58 static struct ptunit_result query(void) 59 { 60 struct pt_retstack retstack; 61 uint64_t ip; 62 int status; 63 64 pt_retstack_init(&retstack); 65 66 status = pt_retstack_push(&retstack, 0x42ull); 67 ptu_int_eq(status, 0); 68 69 status = pt_retstack_is_empty(&retstack); 70 ptu_int_eq(status, 0); 71 72 status = pt_retstack_pop(&retstack, &ip); 73 ptu_int_eq(status, 0); 74 ptu_uint_eq(ip, 0x42ull); 75 76 status = pt_retstack_is_empty(&retstack); 77 ptu_int_ne(status, 0); 78 79 return ptu_passed(); 80 } 81 82 static struct ptunit_result query_empty(void) 83 { 84 struct pt_retstack retstack; 85 uint64_t ip; 86 int status; 87 88 pt_retstack_init(&retstack); 89 90 ip = 0x42ull; 91 status = pt_retstack_pop(&retstack, &ip); 92 ptu_int_eq(status, -pte_retstack_empty); 93 ptu_uint_eq(ip, 0x42ull); 94 95 return ptu_passed(); 96 } 97 98 static struct ptunit_result query_null(void) 99 { 100 uint64_t ip; 101 int status; 102 103 ip = 0x42ull; 104 status = pt_retstack_pop(NULL, &ip); 105 ptu_int_eq(status, -pte_invalid); 106 ptu_uint_eq(ip, 0x42ull); 107 108 return ptu_passed(); 109 } 110 111 static struct ptunit_result pop(void) 112 { 113 struct pt_retstack retstack; 114 int status; 115 116 pt_retstack_init(&retstack); 117 118 status = pt_retstack_push(&retstack, 0x42ull); 119 ptu_int_eq(status, 0); 120 121 status = pt_retstack_is_empty(&retstack); 122 ptu_int_eq(status, 0); 123 124 status = pt_retstack_pop(&retstack, NULL); 125 ptu_int_eq(status, 0); 126 127 status = pt_retstack_is_empty(&retstack); 128 ptu_int_ne(status, 0); 129 130 return ptu_passed(); 131 } 132 133 static struct ptunit_result pop_empty(void) 134 { 135 struct pt_retstack retstack; 136 int status; 137 138 pt_retstack_init(&retstack); 139 140 status = pt_retstack_pop(&retstack, NULL); 141 ptu_int_eq(status, -pte_retstack_empty); 142 143 return ptu_passed(); 144 } 145 146 static struct ptunit_result pop_null(void) 147 { 148 int status; 149 150 status = pt_retstack_pop(NULL, NULL); 151 ptu_int_eq(status, -pte_invalid); 152 153 return ptu_passed(); 154 } 155 156 static struct ptunit_result full(void) 157 { 158 struct pt_retstack retstack; 159 uint64_t ip, idx; 160 int status; 161 162 pt_retstack_init(&retstack); 163 164 for (idx = 0; idx < pt_retstack_size; ++idx) { 165 status = pt_retstack_push(&retstack, idx); 166 ptu_int_eq(status, 0); 167 } 168 169 status = pt_retstack_is_empty(&retstack); 170 ptu_int_eq(status, 0); 171 172 for (idx = pt_retstack_size; idx > 0;) { 173 idx -= 1; 174 175 status = pt_retstack_pop(&retstack, &ip); 176 ptu_int_eq(status, 0); 177 ptu_uint_eq(ip, idx); 178 } 179 180 status = pt_retstack_is_empty(&retstack); 181 ptu_int_ne(status, 0); 182 183 return ptu_passed(); 184 } 185 186 static struct ptunit_result overflow(void) 187 { 188 struct pt_retstack retstack; 189 uint64_t ip, idx; 190 int status; 191 192 pt_retstack_init(&retstack); 193 194 for (idx = 0; idx <= pt_retstack_size; ++idx) { 195 status = pt_retstack_push(&retstack, idx); 196 ptu_int_eq(status, 0); 197 } 198 199 status = pt_retstack_is_empty(&retstack); 200 ptu_int_eq(status, 0); 201 202 for (idx = pt_retstack_size; idx > 0; --idx) { 203 status = pt_retstack_pop(&retstack, &ip); 204 ptu_int_eq(status, 0); 205 ptu_uint_eq(ip, idx); 206 } 207 208 status = pt_retstack_is_empty(&retstack); 209 ptu_int_ne(status, 0); 210 211 return ptu_passed(); 212 } 213 214 int main(int argc, char **argv) 215 { 216 struct ptunit_suite suite; 217 218 suite = ptunit_mk_suite(argc, argv); 219 220 ptu_run(suite, init); 221 ptu_run(suite, init_null); 222 ptu_run(suite, query); 223 ptu_run(suite, query_empty); 224 ptu_run(suite, query_null); 225 ptu_run(suite, pop); 226 ptu_run(suite, pop_empty); 227 ptu_run(suite, pop_null); 228 ptu_run(suite, full); 229 ptu_run(suite, overflow); 230 231 return ptunit_report(&suite); 232 } 233