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
init(void)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
init_null(void)53 static struct ptunit_result init_null(void)
54 {
55 pt_last_ip_init(NULL);
56
57 return ptu_passed();
58 }
59
status_initial(void)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
status(void)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
status_null(void)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
status_noip(void)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
status_suppressed(void)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
query_initial(void)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
query(void)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
query_null(void)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
query_noip(void)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
query_suppressed(void)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
update_ip_suppressed(uint32_t have_ip)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
update_ip_upd16(uint32_t have_ip)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
update_ip_upd32(uint32_t have_ip)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
update_ip_sext48(uint32_t have_ip)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
update_ip_bad_packet(uint32_t have_ip)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
update_ip_null_ip(void)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
update_ip_null_packet(uint32_t have_ip)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
main(int argc,char ** argv)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