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_threads.h"
30 #include "ptunit_mkfile.h"
31
32 #include "pt_section.h"
33 #include "pt_block_cache.h"
34
35 #include "intel-pt.h"
36
37 #include <stdlib.h>
38 #include <stdio.h>
39
40
41
42 struct pt_image_section_cache {
43 int map;
44 };
45
46 extern int pt_iscache_notify_map(struct pt_image_section_cache *iscache,
47 struct pt_section *section);
48 extern int pt_iscache_notify_resize(struct pt_image_section_cache *iscache,
49 struct pt_section *section, uint64_t size);
50
pt_iscache_notify_map(struct pt_image_section_cache * iscache,struct pt_section * section)51 int pt_iscache_notify_map(struct pt_image_section_cache *iscache,
52 struct pt_section *section)
53 {
54 if (!iscache)
55 return -pte_internal;
56
57 if (iscache->map <= 0)
58 return iscache->map;
59
60 /* Avoid recursion. */
61 iscache->map = 0;
62
63 return pt_section_map_share(section);
64 }
65
pt_iscache_notify_resize(struct pt_image_section_cache * iscache,struct pt_section * section,uint64_t size)66 int pt_iscache_notify_resize(struct pt_image_section_cache *iscache,
67 struct pt_section *section, uint64_t size)
68 {
69 uint64_t memsize;
70 int errcode;
71
72 if (!iscache)
73 return -pte_internal;
74
75 if (iscache->map <= 0)
76 return iscache->map;
77
78 /* Avoid recursion. */
79 iscache->map = 0;
80
81 errcode = pt_section_memsize(section, &memsize);
82 if (errcode < 0)
83 return errcode;
84
85 if (size != memsize)
86 return -pte_internal;
87
88 return pt_section_map_share(section);
89 }
90
pt_bcache_alloc(uint64_t nentries)91 struct pt_block_cache *pt_bcache_alloc(uint64_t nentries)
92 {
93 struct pt_block_cache *bcache;
94
95 if (!nentries || (UINT32_MAX < nentries))
96 return NULL;
97
98 /* The cache is not really used by tests. It suffices to allocate only
99 * the cache struct with the single default entry.
100 *
101 * We still set the number of entries to the requested size.
102 */
103 bcache = malloc(sizeof(*bcache));
104 if (bcache)
105 bcache->nentries = (uint32_t) nentries;
106
107 return bcache;
108 }
109
pt_bcache_free(struct pt_block_cache * bcache)110 void pt_bcache_free(struct pt_block_cache *bcache)
111 {
112 free(bcache);
113 }
114
115 /* A test fixture providing a temporary file and an initially NULL section. */
116 struct section_fixture {
117 /* Threading support. */
118 struct ptunit_thrd_fixture thrd;
119
120 /* A temporary file name. */
121 char *name;
122
123 /* That file opened for writing. */
124 FILE *file;
125
126 /* The section. */
127 struct pt_section *section;
128
129 /* The test fixture initialization and finalization functions. */
130 struct ptunit_result (*init)(struct section_fixture *);
131 struct ptunit_result (*fini)(struct section_fixture *);
132 };
133
134 enum {
135 #if defined(FEATURE_THREADS)
136
137 num_threads = 4,
138
139 #endif /* defined(FEATURE_THREADS) */
140
141 num_work = 0x4000
142 };
143
sfix_write_aux(struct section_fixture * sfix,const uint8_t * buffer,size_t size)144 static struct ptunit_result sfix_write_aux(struct section_fixture *sfix,
145 const uint8_t *buffer, size_t size)
146 {
147 size_t written;
148
149 written = fwrite(buffer, 1, size, sfix->file);
150 ptu_uint_eq(written, size);
151
152 fflush(sfix->file);
153
154 return ptu_passed();
155 }
156
157 #define sfix_write(sfix, buffer) \
158 ptu_check(sfix_write_aux, sfix, buffer, sizeof(buffer))
159
create(struct section_fixture * sfix)160 static struct ptunit_result create(struct section_fixture *sfix)
161 {
162 const char *name;
163 uint8_t bytes[] = { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc };
164 uint64_t offset, size;
165 int errcode;
166
167 sfix_write(sfix, bytes);
168
169 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
170 ptu_int_eq(errcode, 0);
171 ptu_ptr(sfix->section);
172
173 name = pt_section_filename(sfix->section);
174 ptu_str_eq(name, sfix->name);
175
176 offset = pt_section_offset(sfix->section);
177 ptu_uint_eq(offset, 0x1ull);
178
179 size = pt_section_size(sfix->section);
180 ptu_uint_eq(size, 0x3ull);
181
182 return ptu_passed();
183 }
184
create_bad_offset(struct section_fixture * sfix)185 static struct ptunit_result create_bad_offset(struct section_fixture *sfix)
186 {
187 int errcode;
188
189 errcode = pt_mk_section(&sfix->section, sfix->name, 0x10ull, 0x0ull);
190 ptu_int_eq(errcode, -pte_invalid);
191
192 return ptu_passed();
193 }
194
create_truncated(struct section_fixture * sfix)195 static struct ptunit_result create_truncated(struct section_fixture *sfix)
196 {
197 const char *name;
198 uint8_t bytes[] = { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc };
199 uint64_t offset, size;
200 int errcode;
201
202 sfix_write(sfix, bytes);
203
204 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, UINT64_MAX);
205 ptu_int_eq(errcode, 0);
206 ptu_ptr(sfix->section);
207
208 name = pt_section_filename(sfix->section);
209 ptu_str_eq(name, sfix->name);
210
211 offset = pt_section_offset(sfix->section);
212 ptu_uint_eq(offset, 0x1ull);
213
214 size = pt_section_size(sfix->section);
215 ptu_uint_eq(size, sizeof(bytes) - 1);
216
217 return ptu_passed();
218 }
219
create_empty(struct section_fixture * sfix)220 static struct ptunit_result create_empty(struct section_fixture *sfix)
221 {
222 int errcode;
223
224 errcode = pt_mk_section(&sfix->section, sfix->name, 0x0ull, 0x10ull);
225 ptu_int_eq(errcode, -pte_invalid);
226 ptu_null(sfix->section);
227
228 return ptu_passed();
229 }
230
filename_null(void)231 static struct ptunit_result filename_null(void)
232 {
233 const char *name;
234
235 name = pt_section_filename(NULL);
236 ptu_null(name);
237
238 return ptu_passed();
239 }
240
size_null(void)241 static struct ptunit_result size_null(void)
242 {
243 uint64_t size;
244
245 size = pt_section_size(NULL);
246 ptu_uint_eq(size, 0ull);
247
248 return ptu_passed();
249 }
250
memsize_null(struct section_fixture * sfix)251 static struct ptunit_result memsize_null(struct section_fixture *sfix)
252 {
253 uint64_t size;
254 int errcode;
255
256 errcode = pt_section_memsize(NULL, &size);
257 ptu_int_eq(errcode, -pte_internal);
258
259 errcode = pt_section_memsize(sfix->section, NULL);
260 ptu_int_eq(errcode, -pte_internal);
261
262 errcode = pt_section_memsize(NULL, NULL);
263 ptu_int_eq(errcode, -pte_internal);
264
265 return ptu_passed();
266 }
267
offset_null(void)268 static struct ptunit_result offset_null(void)
269 {
270 uint64_t offset;
271
272 offset = pt_section_offset(NULL);
273 ptu_uint_eq(offset, 0ull);
274
275 return ptu_passed();
276 }
277
get_null(void)278 static struct ptunit_result get_null(void)
279 {
280 int errcode;
281
282 errcode = pt_section_get(NULL);
283 ptu_int_eq(errcode, -pte_internal);
284
285 return ptu_passed();
286 }
287
put_null(void)288 static struct ptunit_result put_null(void)
289 {
290 int errcode;
291
292 errcode = pt_section_put(NULL);
293 ptu_int_eq(errcode, -pte_internal);
294
295 return ptu_passed();
296 }
297
attach_null(void)298 static struct ptunit_result attach_null(void)
299 {
300 struct pt_image_section_cache iscache;
301 struct pt_section section;
302 int errcode;
303
304 errcode = pt_section_attach(NULL, &iscache);
305 ptu_int_eq(errcode, -pte_internal);
306
307 errcode = pt_section_attach(§ion, NULL);
308 ptu_int_eq(errcode, -pte_internal);
309
310 errcode = pt_section_attach(NULL, NULL);
311 ptu_int_eq(errcode, -pte_internal);
312
313 return ptu_passed();
314 }
315
detach_null(void)316 static struct ptunit_result detach_null(void)
317 {
318 struct pt_image_section_cache iscache;
319 struct pt_section section;
320 int errcode;
321
322 errcode = pt_section_detach(NULL, &iscache);
323 ptu_int_eq(errcode, -pte_internal);
324
325 errcode = pt_section_detach(§ion, NULL);
326 ptu_int_eq(errcode, -pte_internal);
327
328 errcode = pt_section_detach(NULL, NULL);
329 ptu_int_eq(errcode, -pte_internal);
330
331 return ptu_passed();
332 }
333
map_null(void)334 static struct ptunit_result map_null(void)
335 {
336 int errcode;
337
338 errcode = pt_section_map(NULL);
339 ptu_int_eq(errcode, -pte_internal);
340
341 return ptu_passed();
342 }
343
unmap_null(void)344 static struct ptunit_result unmap_null(void)
345 {
346 int errcode;
347
348 errcode = pt_section_unmap(NULL);
349 ptu_int_eq(errcode, -pte_internal);
350
351 return ptu_passed();
352 }
353
cache_null(void)354 static struct ptunit_result cache_null(void)
355 {
356 struct pt_block_cache *bcache;
357
358 bcache = pt_section_bcache(NULL);
359 ptu_null(bcache);
360
361 return ptu_passed();
362 }
363
get_overflow(struct section_fixture * sfix)364 static struct ptunit_result get_overflow(struct section_fixture *sfix)
365 {
366 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
367 int errcode;
368
369 sfix_write(sfix, bytes);
370
371 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
372 ptu_int_eq(errcode, 0);
373 ptu_ptr(sfix->section);
374
375 sfix->section->ucount = UINT16_MAX;
376
377 errcode = pt_section_get(sfix->section);
378 ptu_int_eq(errcode, -pte_overflow);
379
380 sfix->section->ucount = 1;
381
382 return ptu_passed();
383 }
384
attach_overflow(struct section_fixture * sfix)385 static struct ptunit_result attach_overflow(struct section_fixture *sfix)
386 {
387 struct pt_image_section_cache iscache;
388 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
389 int errcode;
390
391 sfix_write(sfix, bytes);
392
393 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
394 ptu_int_eq(errcode, 0);
395 ptu_ptr(sfix->section);
396
397 sfix->section->acount = UINT16_MAX;
398
399 errcode = pt_section_attach(sfix->section, &iscache);
400 ptu_int_eq(errcode, -pte_overflow);
401
402 sfix->section->acount = 0;
403
404 return ptu_passed();
405 }
406
attach_bad_ucount(struct section_fixture * sfix)407 static struct ptunit_result attach_bad_ucount(struct section_fixture *sfix)
408 {
409 struct pt_image_section_cache iscache;
410 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
411 int errcode;
412
413 sfix_write(sfix, bytes);
414
415 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
416 ptu_int_eq(errcode, 0);
417 ptu_ptr(sfix->section);
418
419 sfix->section->acount = 2;
420
421 errcode = pt_section_attach(sfix->section, &iscache);
422 ptu_int_eq(errcode, -pte_internal);
423
424 sfix->section->acount = 0;
425
426 return ptu_passed();
427 }
428
map_change(struct section_fixture * sfix)429 static struct ptunit_result map_change(struct section_fixture *sfix)
430 {
431 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
432 int errcode;
433
434 sfix_write(sfix, bytes);
435
436 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
437 ptu_int_eq(errcode, 0);
438 ptu_ptr(sfix->section);
439
440 sfix_write(sfix, bytes);
441
442 errcode = pt_section_map(sfix->section);
443 ptu_int_eq(errcode, -pte_bad_image);
444
445 return ptu_passed();
446 }
447
map_put(struct section_fixture * sfix)448 static struct ptunit_result map_put(struct section_fixture *sfix)
449 {
450 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
451 int errcode;
452
453 sfix_write(sfix, bytes);
454
455 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
456 ptu_int_eq(errcode, 0);
457 ptu_ptr(sfix->section);
458
459 errcode = pt_section_map(sfix->section);
460 ptu_int_eq(errcode, 0);
461
462 errcode = pt_section_put(sfix->section);
463 ptu_int_eq(errcode, -pte_internal);
464
465 errcode = pt_section_unmap(sfix->section);
466 ptu_int_eq(errcode, 0);
467
468 return ptu_passed();
469 }
470
unmap_nomap(struct section_fixture * sfix)471 static struct ptunit_result unmap_nomap(struct section_fixture *sfix)
472 {
473 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
474 int errcode;
475
476 sfix_write(sfix, bytes);
477
478 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
479 ptu_int_eq(errcode, 0);
480 ptu_ptr(sfix->section);
481
482 errcode = pt_section_unmap(sfix->section);
483 ptu_int_eq(errcode, -pte_nomap);
484
485 return ptu_passed();
486 }
487
map_overflow(struct section_fixture * sfix)488 static struct ptunit_result map_overflow(struct section_fixture *sfix)
489 {
490 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
491 int errcode;
492
493 sfix_write(sfix, bytes);
494
495 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
496 ptu_int_eq(errcode, 0);
497 ptu_ptr(sfix->section);
498
499 sfix->section->mcount = UINT16_MAX;
500
501 errcode = pt_section_map(sfix->section);
502 ptu_int_eq(errcode, -pte_overflow);
503
504 sfix->section->mcount = 0;
505
506 return ptu_passed();
507 }
508
get_put(struct section_fixture * sfix)509 static struct ptunit_result get_put(struct section_fixture *sfix)
510 {
511 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
512 int errcode;
513
514 sfix_write(sfix, bytes);
515
516 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
517 ptu_int_eq(errcode, 0);
518 ptu_ptr(sfix->section);
519
520 errcode = pt_section_get(sfix->section);
521 ptu_int_eq(errcode, 0);
522
523 errcode = pt_section_get(sfix->section);
524 ptu_int_eq(errcode, 0);
525
526 errcode = pt_section_put(sfix->section);
527 ptu_int_eq(errcode, 0);
528
529 errcode = pt_section_put(sfix->section);
530 ptu_int_eq(errcode, 0);
531
532 return ptu_passed();
533 }
534
attach_detach(struct section_fixture * sfix)535 static struct ptunit_result attach_detach(struct section_fixture *sfix)
536 {
537 struct pt_image_section_cache iscache;
538 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
539 int errcode;
540
541 sfix_write(sfix, bytes);
542
543 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
544 ptu_int_eq(errcode, 0);
545 ptu_ptr(sfix->section);
546
547 sfix->section->ucount += 2;
548
549 errcode = pt_section_attach(sfix->section, &iscache);
550 ptu_int_eq(errcode, 0);
551
552 errcode = pt_section_attach(sfix->section, &iscache);
553 ptu_int_eq(errcode, 0);
554
555 errcode = pt_section_detach(sfix->section, &iscache);
556 ptu_int_eq(errcode, 0);
557
558 errcode = pt_section_detach(sfix->section, &iscache);
559 ptu_int_eq(errcode, 0);
560
561 sfix->section->ucount -= 2;
562
563 return ptu_passed();
564 }
565
attach_bad_iscache(struct section_fixture * sfix)566 static struct ptunit_result attach_bad_iscache(struct section_fixture *sfix)
567 {
568 struct pt_image_section_cache iscache, bad;
569 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
570 int errcode;
571
572 sfix_write(sfix, bytes);
573
574 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
575 ptu_int_eq(errcode, 0);
576 ptu_ptr(sfix->section);
577
578 sfix->section->ucount += 2;
579
580 errcode = pt_section_attach(sfix->section, &iscache);
581 ptu_int_eq(errcode, 0);
582
583 errcode = pt_section_attach(sfix->section, &bad);
584 ptu_int_eq(errcode, -pte_internal);
585
586 errcode = pt_section_detach(sfix->section, &iscache);
587 ptu_int_eq(errcode, 0);
588
589 sfix->section->ucount -= 2;
590
591 return ptu_passed();
592 }
593
detach_bad_iscache(struct section_fixture * sfix)594 static struct ptunit_result detach_bad_iscache(struct section_fixture *sfix)
595 {
596 struct pt_image_section_cache iscache, bad;
597 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
598 int errcode;
599
600 sfix_write(sfix, bytes);
601
602 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
603 ptu_int_eq(errcode, 0);
604 ptu_ptr(sfix->section);
605
606 errcode = pt_section_attach(sfix->section, &iscache);
607 ptu_int_eq(errcode, 0);
608
609 errcode = pt_section_detach(sfix->section, &bad);
610 ptu_int_eq(errcode, -pte_internal);
611
612 errcode = pt_section_detach(sfix->section, &iscache);
613 ptu_int_eq(errcode, 0);
614
615 return ptu_passed();
616 }
617
map_unmap(struct section_fixture * sfix)618 static struct ptunit_result map_unmap(struct section_fixture *sfix)
619 {
620 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
621 int errcode;
622
623 sfix_write(sfix, bytes);
624
625 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
626 ptu_int_eq(errcode, 0);
627 ptu_ptr(sfix->section);
628
629 errcode = pt_section_map(sfix->section);
630 ptu_int_eq(errcode, 0);
631
632 errcode = pt_section_map(sfix->section);
633 ptu_int_eq(errcode, 0);
634
635 errcode = pt_section_unmap(sfix->section);
636 ptu_int_eq(errcode, 0);
637
638 errcode = pt_section_unmap(sfix->section);
639 ptu_int_eq(errcode, 0);
640
641 return ptu_passed();
642 }
643
attach_map(struct section_fixture * sfix)644 static struct ptunit_result attach_map(struct section_fixture *sfix)
645 {
646 struct pt_image_section_cache iscache;
647 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
648 int errcode;
649
650 iscache.map = 0;
651
652 sfix_write(sfix, bytes);
653
654 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
655 ptu_int_eq(errcode, 0);
656 ptu_ptr(sfix->section);
657
658 errcode = pt_section_attach(sfix->section, &iscache);
659 ptu_int_eq(errcode, 0);
660
661 errcode = pt_section_map(sfix->section);
662 ptu_int_eq(errcode, 0);
663
664 errcode = pt_section_map(sfix->section);
665 ptu_int_eq(errcode, 0);
666
667 ptu_uint_eq(sfix->section->mcount, 2);
668
669 errcode = pt_section_unmap(sfix->section);
670 ptu_int_eq(errcode, 0);
671
672 errcode = pt_section_unmap(sfix->section);
673 ptu_int_eq(errcode, 0);
674
675 errcode = pt_section_detach(sfix->section, &iscache);
676 ptu_int_eq(errcode, 0);
677
678 return ptu_passed();
679 }
680
attach_bad_map(struct section_fixture * sfix)681 static struct ptunit_result attach_bad_map(struct section_fixture *sfix)
682 {
683 struct pt_image_section_cache iscache;
684 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
685 int errcode;
686
687 iscache.map = -pte_eos;
688
689 sfix_write(sfix, bytes);
690
691 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
692 ptu_int_eq(errcode, 0);
693 ptu_ptr(sfix->section);
694
695 errcode = pt_section_attach(sfix->section, &iscache);
696 ptu_int_eq(errcode, 0);
697
698 errcode = pt_section_map(sfix->section);
699 ptu_int_eq(errcode, -pte_eos);
700
701 errcode = pt_section_detach(sfix->section, &iscache);
702 ptu_int_eq(errcode, 0);
703
704 return ptu_passed();
705 }
706
attach_map_overflow(struct section_fixture * sfix)707 static struct ptunit_result attach_map_overflow(struct section_fixture *sfix)
708 {
709 struct pt_image_section_cache iscache;
710 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
711 int errcode;
712
713 iscache.map = 1;
714
715 sfix_write(sfix, bytes);
716
717 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
718 ptu_int_eq(errcode, 0);
719 ptu_ptr(sfix->section);
720
721 errcode = pt_section_attach(sfix->section, &iscache);
722 ptu_int_eq(errcode, 0);
723
724 sfix->section->mcount = UINT16_MAX - 1;
725
726 errcode = pt_section_map(sfix->section);
727 ptu_int_eq(errcode, -pte_overflow);
728
729 errcode = pt_section_detach(sfix->section, &iscache);
730 ptu_int_eq(errcode, 0);
731
732 return ptu_passed();
733 }
734
read(struct section_fixture * sfix)735 static struct ptunit_result read(struct section_fixture *sfix)
736 {
737 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
738 uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
739 int status;
740
741 sfix_write(sfix, bytes);
742
743 status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
744 ptu_int_eq(status, 0);
745 ptu_ptr(sfix->section);
746
747 status = pt_section_map(sfix->section);
748 ptu_int_eq(status, 0);
749
750 status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
751 ptu_int_eq(status, 2);
752 ptu_uint_eq(buffer[0], bytes[1]);
753 ptu_uint_eq(buffer[1], bytes[2]);
754 ptu_uint_eq(buffer[2], 0xcc);
755
756 status = pt_section_unmap(sfix->section);
757 ptu_int_eq(status, 0);
758
759 return ptu_passed();
760 }
761
read_null(struct section_fixture * sfix)762 static struct ptunit_result read_null(struct section_fixture *sfix)
763 {
764 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
765 uint8_t buffer[] = { 0xcc };
766 int status;
767
768 sfix_write(sfix, bytes);
769
770 status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
771 ptu_int_eq(status, 0);
772 ptu_ptr(sfix->section);
773
774 status = pt_section_map(sfix->section);
775 ptu_int_eq(status, 0);
776
777 status = pt_section_read(sfix->section, NULL, 1, 0x0ull);
778 ptu_int_eq(status, -pte_internal);
779 ptu_uint_eq(buffer[0], 0xcc);
780
781 status = pt_section_read(NULL, buffer, 1, 0x0ull);
782 ptu_int_eq(status, -pte_internal);
783 ptu_uint_eq(buffer[0], 0xcc);
784
785 status = pt_section_unmap(sfix->section);
786 ptu_int_eq(status, 0);
787
788 return ptu_passed();
789 }
790
read_offset(struct section_fixture * sfix)791 static struct ptunit_result read_offset(struct section_fixture *sfix)
792 {
793 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
794 uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
795 int status;
796
797 sfix_write(sfix, bytes);
798
799 status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
800 ptu_int_eq(status, 0);
801 ptu_ptr(sfix->section);
802
803 status = pt_section_map(sfix->section);
804 ptu_int_eq(status, 0);
805
806 status = pt_section_read(sfix->section, buffer, 2, 0x1ull);
807 ptu_int_eq(status, 2);
808 ptu_uint_eq(buffer[0], bytes[2]);
809 ptu_uint_eq(buffer[1], bytes[3]);
810 ptu_uint_eq(buffer[2], 0xcc);
811
812 status = pt_section_unmap(sfix->section);
813 ptu_int_eq(status, 0);
814
815 return ptu_passed();
816 }
817
read_truncated(struct section_fixture * sfix)818 static struct ptunit_result read_truncated(struct section_fixture *sfix)
819 {
820 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc, 0xcc };
821 int status;
822
823 sfix_write(sfix, bytes);
824
825 status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
826 ptu_int_eq(status, 0);
827 ptu_ptr(sfix->section);
828
829 status = pt_section_map(sfix->section);
830 ptu_int_eq(status, 0);
831
832 status = pt_section_read(sfix->section, buffer, 2, 0x2ull);
833 ptu_int_eq(status, 1);
834 ptu_uint_eq(buffer[0], bytes[3]);
835 ptu_uint_eq(buffer[1], 0xcc);
836
837 status = pt_section_unmap(sfix->section);
838 ptu_int_eq(status, 0);
839
840 return ptu_passed();
841 }
842
read_from_truncated(struct section_fixture * sfix)843 static struct ptunit_result read_from_truncated(struct section_fixture *sfix)
844 {
845 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc, 0xcc };
846 int status;
847
848 sfix_write(sfix, bytes);
849
850 status = pt_mk_section(&sfix->section, sfix->name, 0x2ull, 0x10ull);
851 ptu_int_eq(status, 0);
852 ptu_ptr(sfix->section);
853
854 status = pt_section_map(sfix->section);
855 ptu_int_eq(status, 0);
856
857 status = pt_section_read(sfix->section, buffer, 2, 0x1ull);
858 ptu_int_eq(status, 1);
859 ptu_uint_eq(buffer[0], bytes[3]);
860 ptu_uint_eq(buffer[1], 0xcc);
861
862 status = pt_section_unmap(sfix->section);
863 ptu_int_eq(status, 0);
864
865 return ptu_passed();
866 }
867
read_nomem(struct section_fixture * sfix)868 static struct ptunit_result read_nomem(struct section_fixture *sfix)
869 {
870 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
871 int status;
872
873 sfix_write(sfix, bytes);
874
875 status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
876 ptu_int_eq(status, 0);
877 ptu_ptr(sfix->section);
878
879 status = pt_section_map(sfix->section);
880 ptu_int_eq(status, 0);
881
882 status = pt_section_read(sfix->section, buffer, 1, 0x3ull);
883 ptu_int_eq(status, -pte_nomap);
884 ptu_uint_eq(buffer[0], 0xcc);
885
886 status = pt_section_unmap(sfix->section);
887 ptu_int_eq(status, 0);
888
889 return ptu_passed();
890 }
891
read_overflow(struct section_fixture * sfix)892 static struct ptunit_result read_overflow(struct section_fixture *sfix)
893 {
894 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
895 int status;
896
897 sfix_write(sfix, bytes);
898
899 status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
900 ptu_int_eq(status, 0);
901 ptu_ptr(sfix->section);
902
903 status = pt_section_map(sfix->section);
904 ptu_int_eq(status, 0);
905
906 status = pt_section_read(sfix->section, buffer, 1,
907 0xffffffffffff0000ull);
908 ptu_int_eq(status, -pte_nomap);
909 ptu_uint_eq(buffer[0], 0xcc);
910
911 status = pt_section_unmap(sfix->section);
912 ptu_int_eq(status, 0);
913
914 return ptu_passed();
915 }
916
read_overflow_32bit(struct section_fixture * sfix)917 static struct ptunit_result read_overflow_32bit(struct section_fixture *sfix)
918 {
919 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
920 int status;
921
922 sfix_write(sfix, bytes);
923
924 status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
925 ptu_int_eq(status, 0);
926 ptu_ptr(sfix->section);
927
928 status = pt_section_map(sfix->section);
929 ptu_int_eq(status, 0);
930
931 status = pt_section_read(sfix->section, buffer, 1,
932 0xff00000000ull);
933 ptu_int_eq(status, -pte_nomap);
934 ptu_uint_eq(buffer[0], 0xcc);
935
936 status = pt_section_unmap(sfix->section);
937 ptu_int_eq(status, 0);
938
939 return ptu_passed();
940 }
941
read_nomap(struct section_fixture * sfix)942 static struct ptunit_result read_nomap(struct section_fixture *sfix)
943 {
944 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
945 int status;
946
947 sfix_write(sfix, bytes);
948
949 status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
950 ptu_int_eq(status, 0);
951 ptu_ptr(sfix->section);
952
953 status = pt_section_read(sfix->section, buffer, 1, 0x0ull);
954 ptu_int_eq(status, -pte_nomap);
955 ptu_uint_eq(buffer[0], 0xcc);
956
957 return ptu_passed();
958 }
959
read_unmap_map(struct section_fixture * sfix)960 static struct ptunit_result read_unmap_map(struct section_fixture *sfix)
961 {
962 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
963 uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
964 int status;
965
966 sfix_write(sfix, bytes);
967
968 status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
969 ptu_int_eq(status, 0);
970 ptu_ptr(sfix->section);
971
972 status = pt_section_map(sfix->section);
973 ptu_int_eq(status, 0);
974
975 status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
976 ptu_int_eq(status, 2);
977 ptu_uint_eq(buffer[0], bytes[1]);
978 ptu_uint_eq(buffer[1], bytes[2]);
979 ptu_uint_eq(buffer[2], 0xcc);
980
981 memset(buffer, 0xcc, sizeof(buffer));
982
983 status = pt_section_unmap(sfix->section);
984 ptu_int_eq(status, 0);
985
986 status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
987 ptu_int_eq(status, -pte_nomap);
988 ptu_uint_eq(buffer[0], 0xcc);
989 ptu_uint_eq(buffer[1], 0xcc);
990 ptu_uint_eq(buffer[2], 0xcc);
991
992 status = pt_section_map(sfix->section);
993 ptu_int_eq(status, 0);
994
995 status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
996 ptu_int_eq(status, 2);
997 ptu_uint_eq(buffer[0], bytes[1]);
998 ptu_uint_eq(buffer[1], bytes[2]);
999 ptu_uint_eq(buffer[2], 0xcc);
1000
1001 status = pt_section_unmap(sfix->section);
1002 ptu_int_eq(status, 0);
1003
1004 return ptu_passed();
1005 }
1006
worker_read(void * arg)1007 static int worker_read(void *arg)
1008 {
1009 struct section_fixture *sfix;
1010 int it, errcode;
1011
1012 sfix = arg;
1013 if (!sfix)
1014 return -pte_internal;
1015
1016 for (it = 0; it < num_work; ++it) {
1017 uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1018 int read;
1019
1020 errcode = pt_section_get(sfix->section);
1021 if (errcode < 0)
1022 return errcode;
1023
1024 errcode = pt_section_map(sfix->section);
1025 if (errcode < 0)
1026 goto out_put;
1027
1028 read = pt_section_read(sfix->section, buffer, 2, 0x0ull);
1029 if (read < 0)
1030 goto out_unmap;
1031
1032 errcode = -pte_invalid;
1033 if ((read != 2) || (buffer[0] != 0x2) || (buffer[1] != 0x4))
1034 goto out_unmap;
1035
1036 errcode = pt_section_unmap(sfix->section);
1037 if (errcode < 0)
1038 goto out_put;
1039
1040 errcode = pt_section_put(sfix->section);
1041 if (errcode < 0)
1042 return errcode;
1043 }
1044
1045 return 0;
1046
1047 out_unmap:
1048 (void) pt_section_unmap(sfix->section);
1049
1050 out_put:
1051 (void) pt_section_put(sfix->section);
1052 return errcode;
1053 }
1054
worker_bcache(void * arg)1055 static int worker_bcache(void *arg)
1056 {
1057 struct section_fixture *sfix;
1058 int it, errcode;
1059
1060 sfix = arg;
1061 if (!sfix)
1062 return -pte_internal;
1063
1064 errcode = pt_section_get(sfix->section);
1065 if (errcode < 0)
1066 return errcode;
1067
1068 for (it = 0; it < num_work; ++it) {
1069 struct pt_block_cache *bcache;
1070
1071 errcode = pt_section_map(sfix->section);
1072 if (errcode < 0)
1073 goto out_put;
1074
1075 errcode = pt_section_request_bcache(sfix->section);
1076 if (errcode < 0)
1077 goto out_unmap;
1078
1079 bcache = pt_section_bcache(sfix->section);
1080 if (!bcache) {
1081 errcode = -pte_nomem;
1082 goto out_unmap;
1083 }
1084
1085 errcode = pt_section_unmap(sfix->section);
1086 if (errcode < 0)
1087 goto out_put;
1088 }
1089
1090 return pt_section_put(sfix->section);
1091
1092 out_unmap:
1093 (void) pt_section_unmap(sfix->section);
1094
1095 out_put:
1096 (void) pt_section_put(sfix->section);
1097 return errcode;
1098 }
1099
stress(struct section_fixture * sfix,int (* worker)(void *))1100 static struct ptunit_result stress(struct section_fixture *sfix,
1101 int (*worker)(void *))
1102 {
1103 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1104 int errcode;
1105
1106 sfix_write(sfix, bytes);
1107
1108 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1109 ptu_int_eq(errcode, 0);
1110 ptu_ptr(sfix->section);
1111
1112 #if defined(FEATURE_THREADS)
1113 {
1114 int thrd;
1115
1116 for (thrd = 0; thrd < num_threads; ++thrd)
1117 ptu_test(ptunit_thrd_create, &sfix->thrd, worker, sfix);
1118 }
1119 #endif /* defined(FEATURE_THREADS) */
1120
1121 errcode = worker(sfix);
1122 ptu_int_eq(errcode, 0);
1123
1124 return ptu_passed();
1125 }
1126
init_no_bcache(struct section_fixture * sfix)1127 static struct ptunit_result init_no_bcache(struct section_fixture *sfix)
1128 {
1129 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1130 struct pt_block_cache *bcache;
1131 int errcode;
1132
1133 sfix_write(sfix, bytes);
1134
1135 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1136 ptu_int_eq(errcode, 0);
1137 ptu_ptr(sfix->section);
1138
1139 errcode = pt_section_map(sfix->section);
1140 ptu_int_eq(errcode, 0);
1141
1142 bcache = pt_section_bcache(sfix->section);
1143 ptu_null(bcache);
1144
1145 errcode = pt_section_unmap(sfix->section);
1146 ptu_int_eq(errcode, 0);
1147
1148 return ptu_passed();
1149 }
1150
bcache_alloc_free(struct section_fixture * sfix)1151 static struct ptunit_result bcache_alloc_free(struct section_fixture *sfix)
1152 {
1153 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1154 struct pt_block_cache *bcache;
1155 int errcode;
1156
1157 sfix_write(sfix, bytes);
1158
1159 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1160 ptu_int_eq(errcode, 0);
1161 ptu_ptr(sfix->section);
1162
1163 errcode = pt_section_map(sfix->section);
1164 ptu_int_eq(errcode, 0);
1165
1166 errcode = pt_section_alloc_bcache(sfix->section);
1167 ptu_int_eq(errcode, 0);
1168
1169 bcache = pt_section_bcache(sfix->section);
1170 ptu_ptr(bcache);
1171 ptu_uint_eq(bcache->nentries, sfix->section->size);
1172
1173 errcode = pt_section_unmap(sfix->section);
1174 ptu_int_eq(errcode, 0);
1175
1176 bcache = pt_section_bcache(sfix->section);
1177 ptu_null(bcache);
1178
1179 return ptu_passed();
1180 }
1181
bcache_alloc_twice(struct section_fixture * sfix)1182 static struct ptunit_result bcache_alloc_twice(struct section_fixture *sfix)
1183 {
1184 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1185 int errcode;
1186
1187 sfix_write(sfix, bytes);
1188
1189 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1190 ptu_int_eq(errcode, 0);
1191 ptu_ptr(sfix->section);
1192
1193 errcode = pt_section_map(sfix->section);
1194 ptu_int_eq(errcode, 0);
1195
1196 errcode = pt_section_alloc_bcache(sfix->section);
1197 ptu_int_eq(errcode, 0);
1198
1199 errcode = pt_section_alloc_bcache(sfix->section);
1200 ptu_int_eq(errcode, 0);
1201
1202 errcode = pt_section_unmap(sfix->section);
1203 ptu_int_eq(errcode, 0);
1204
1205 return ptu_passed();
1206 }
1207
bcache_alloc_nomap(struct section_fixture * sfix)1208 static struct ptunit_result bcache_alloc_nomap(struct section_fixture *sfix)
1209 {
1210 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1211 int errcode;
1212
1213 sfix_write(sfix, bytes);
1214
1215 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1216 ptu_int_eq(errcode, 0);
1217 ptu_ptr(sfix->section);
1218
1219 errcode = pt_section_alloc_bcache(sfix->section);
1220 ptu_int_eq(errcode, -pte_internal);
1221
1222 return ptu_passed();
1223 }
1224
memsize_nomap(struct section_fixture * sfix)1225 static struct ptunit_result memsize_nomap(struct section_fixture *sfix)
1226 {
1227 uint64_t memsize;
1228 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1229 int errcode;
1230
1231 sfix_write(sfix, bytes);
1232
1233 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1234 ptu_int_eq(errcode, 0);
1235 ptu_ptr(sfix->section);
1236
1237 errcode = pt_section_memsize(sfix->section, &memsize);
1238 ptu_int_eq(errcode, 0);
1239 ptu_uint_eq(memsize, 0ull);
1240
1241 return ptu_passed();
1242 }
1243
memsize_unmap(struct section_fixture * sfix)1244 static struct ptunit_result memsize_unmap(struct section_fixture *sfix)
1245 {
1246 uint64_t memsize;
1247 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1248 int errcode;
1249
1250 sfix_write(sfix, bytes);
1251
1252 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1253 ptu_int_eq(errcode, 0);
1254 ptu_ptr(sfix->section);
1255
1256 errcode = pt_section_map(sfix->section);
1257 ptu_int_eq(errcode, 0);
1258
1259 errcode = pt_section_unmap(sfix->section);
1260 ptu_int_eq(errcode, 0);
1261
1262 errcode = pt_section_memsize(sfix->section, &memsize);
1263 ptu_int_eq(errcode, 0);
1264 ptu_uint_eq(memsize, 0ull);
1265
1266 return ptu_passed();
1267 }
1268
memsize_map_nobcache(struct section_fixture * sfix)1269 static struct ptunit_result memsize_map_nobcache(struct section_fixture *sfix)
1270 {
1271 uint64_t memsize;
1272 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1273 int errcode;
1274
1275 sfix_write(sfix, bytes);
1276
1277 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1278 ptu_int_eq(errcode, 0);
1279 ptu_ptr(sfix->section);
1280
1281 errcode = pt_section_map(sfix->section);
1282 ptu_int_eq(errcode, 0);
1283
1284 memsize = 0xfefefefefefefefeull;
1285
1286 errcode = pt_section_memsize(sfix->section, &memsize);
1287 ptu_int_eq(errcode, 0);
1288 ptu_uint_ge(memsize, 0ull);
1289 ptu_uint_le(memsize, 0x2000ull);
1290
1291 errcode = pt_section_unmap(sfix->section);
1292 ptu_int_eq(errcode, 0);
1293
1294 return ptu_passed();
1295 }
1296
memsize_map_bcache(struct section_fixture * sfix)1297 static struct ptunit_result memsize_map_bcache(struct section_fixture *sfix)
1298 {
1299 uint64_t memsize;
1300 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1301 int errcode;
1302
1303 sfix_write(sfix, bytes);
1304
1305 errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1306 ptu_int_eq(errcode, 0);
1307 ptu_ptr(sfix->section);
1308
1309 errcode = pt_section_map(sfix->section);
1310 ptu_int_eq(errcode, 0);
1311
1312 errcode = pt_section_alloc_bcache(sfix->section);
1313 ptu_int_eq(errcode, 0);
1314
1315 errcode = pt_section_memsize(sfix->section, &memsize);
1316 ptu_int_eq(errcode, 0);
1317 ptu_uint_ge(memsize,
1318 sfix->section->size * sizeof(struct pt_bcache_entry));
1319
1320 errcode = pt_section_unmap(sfix->section);
1321 ptu_int_eq(errcode, 0);
1322
1323 return ptu_passed();
1324 }
1325
sfix_init(struct section_fixture * sfix)1326 static struct ptunit_result sfix_init(struct section_fixture *sfix)
1327 {
1328 int errcode;
1329
1330 sfix->section = NULL;
1331 sfix->file = NULL;
1332 sfix->name = NULL;
1333
1334 errcode = ptunit_mkfile(&sfix->file, &sfix->name, "wb");
1335 ptu_int_eq(errcode, 0);
1336
1337 ptu_test(ptunit_thrd_init, &sfix->thrd);
1338
1339 return ptu_passed();
1340 }
1341
sfix_fini(struct section_fixture * sfix)1342 static struct ptunit_result sfix_fini(struct section_fixture *sfix)
1343 {
1344 char *filename;
1345 FILE *file;
1346 int thrd, errcode;
1347
1348 ptu_test(ptunit_thrd_fini, &sfix->thrd);
1349
1350 if (sfix->section) {
1351 pt_section_put(sfix->section);
1352 sfix->section = NULL;
1353 }
1354
1355 filename = sfix->name;
1356 file = sfix->file;
1357 sfix->name = NULL;
1358 sfix->file = NULL;
1359
1360 /* Try removing the file while we still have it open to avoid races
1361 * with others re-using the temporary filename.
1362 *
1363 * On some systems that may not be possible and we can choose between:
1364 *
1365 * - guaranteed leaking files or
1366 * - running the risk of removing someone elses file
1367 *
1368 * We choose the latter. Assuming those systems behave consistently,
1369 * removing someone elses file should only succeed if it isn't open at
1370 * the moment we try removing it. Given that this is a temporary file,
1371 * we should be able to rule out accidental name clashes with
1372 * non-termporary files.
1373 */
1374 if (filename && file) {
1375 errcode = remove(filename);
1376 if (!errcode) {
1377 free(filename);
1378 filename = NULL;
1379 }
1380 }
1381
1382 if (file)
1383 fclose(file);
1384
1385 if (filename) {
1386 (void) remove(filename);
1387 free(filename);
1388 }
1389
1390 for (thrd = 0; thrd < sfix->thrd.nthreads; ++thrd)
1391 ptu_int_eq(sfix->thrd.result[thrd], 0);
1392
1393 return ptu_passed();
1394 }
1395
main(int argc,char ** argv)1396 int main(int argc, char **argv)
1397 {
1398 struct section_fixture sfix;
1399 struct ptunit_suite suite;
1400
1401 sfix.init = sfix_init;
1402 sfix.fini = sfix_fini;
1403
1404 suite = ptunit_mk_suite(argc, argv);
1405
1406 ptu_run_f(suite, create, sfix);
1407 ptu_run_f(suite, create_bad_offset, sfix);
1408 ptu_run_f(suite, create_truncated, sfix);
1409 ptu_run_f(suite, create_empty, sfix);
1410
1411 ptu_run(suite, filename_null);
1412 ptu_run(suite, offset_null);
1413 ptu_run(suite, size_null);
1414 ptu_run(suite, get_null);
1415 ptu_run(suite, put_null);
1416 ptu_run(suite, attach_null);
1417 ptu_run(suite, detach_null);
1418 ptu_run(suite, map_null);
1419 ptu_run(suite, unmap_null);
1420 ptu_run(suite, cache_null);
1421
1422 ptu_run_f(suite, get_overflow, sfix);
1423 ptu_run_f(suite, attach_overflow, sfix);
1424 ptu_run_f(suite, attach_bad_ucount, sfix);
1425 ptu_run_f(suite, map_change, sfix);
1426 ptu_run_f(suite, map_put, sfix);
1427 ptu_run_f(suite, unmap_nomap, sfix);
1428 ptu_run_f(suite, map_overflow, sfix);
1429 ptu_run_f(suite, get_put, sfix);
1430 ptu_run_f(suite, attach_detach, sfix);
1431 ptu_run_f(suite, attach_bad_iscache, sfix);
1432 ptu_run_f(suite, detach_bad_iscache, sfix);
1433 ptu_run_f(suite, map_unmap, sfix);
1434 ptu_run_f(suite, attach_map, sfix);
1435 ptu_run_f(suite, attach_bad_map, sfix);
1436 ptu_run_f(suite, attach_map_overflow, sfix);
1437 ptu_run_f(suite, read, sfix);
1438 ptu_run_f(suite, read_null, sfix);
1439 ptu_run_f(suite, read_offset, sfix);
1440 ptu_run_f(suite, read_truncated, sfix);
1441 ptu_run_f(suite, read_from_truncated, sfix);
1442 ptu_run_f(suite, read_nomem, sfix);
1443 ptu_run_f(suite, read_overflow, sfix);
1444 ptu_run_f(suite, read_overflow_32bit, sfix);
1445 ptu_run_f(suite, read_nomap, sfix);
1446 ptu_run_f(suite, read_unmap_map, sfix);
1447
1448 ptu_run_f(suite, init_no_bcache, sfix);
1449 ptu_run_f(suite, bcache_alloc_free, sfix);
1450 ptu_run_f(suite, bcache_alloc_twice, sfix);
1451 ptu_run_f(suite, bcache_alloc_nomap, sfix);
1452
1453 ptu_run_f(suite, memsize_null, sfix);
1454 ptu_run_f(suite, memsize_nomap, sfix);
1455 ptu_run_f(suite, memsize_unmap, sfix);
1456 ptu_run_f(suite, memsize_map_nobcache, sfix);
1457 ptu_run_f(suite, memsize_map_bcache, sfix);
1458
1459 ptu_run_fp(suite, stress, sfix, worker_bcache);
1460 ptu_run_fp(suite, stress, sfix, worker_read);
1461
1462 return ptunit_report(&suite);
1463 }
1464