2 * Copyright (c) 2013-2018, Intel Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
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.
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.
29 #include "ptunit_threads.h"
30 #include "ptunit_mkfile.h"
32 #include "pt_section.h"
33 #include "pt_block_cache.h"
42 struct pt_image_section_cache {
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);
51 int pt_iscache_notify_map(struct pt_image_section_cache *iscache,
52 struct pt_section *section)
57 if (iscache->map <= 0)
60 /* Avoid recursion. */
63 return pt_section_map_share(section);
66 int pt_iscache_notify_resize(struct pt_image_section_cache *iscache,
67 struct pt_section *section, uint64_t size)
75 if (iscache->map <= 0)
78 /* Avoid recursion. */
81 errcode = pt_section_memsize(section, &memsize);
88 return pt_section_map_share(section);
91 struct pt_block_cache *pt_bcache_alloc(uint64_t nentries)
93 struct pt_block_cache *bcache;
95 if (!nentries || (UINT32_MAX < nentries))
98 /* The cache is not really used by tests. It suffices to allocate only
99 * the cache struct with the single default entry.
101 * We still set the number of entries to the requested size.
103 bcache = malloc(sizeof(*bcache));
105 bcache->nentries = (uint32_t) nentries;
110 void pt_bcache_free(struct pt_block_cache *bcache)
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;
120 /* A temporary file name. */
123 /* That file opened for writing. */
127 struct pt_section *section;
129 /* The test fixture initialization and finalization functions. */
130 struct ptunit_result (*init)(struct section_fixture *);
131 struct ptunit_result (*fini)(struct section_fixture *);
135 #if defined(FEATURE_THREADS)
139 #endif /* defined(FEATURE_THREADS) */
144 static struct ptunit_result sfix_write_aux(struct section_fixture *sfix,
145 const uint8_t *buffer, size_t size)
149 written = fwrite(buffer, 1, size, sfix->file);
150 ptu_uint_eq(written, size);
157 #define sfix_write(sfix, buffer) \
158 ptu_check(sfix_write_aux, sfix, buffer, sizeof(buffer))
160 static struct ptunit_result create(struct section_fixture *sfix)
163 uint8_t bytes[] = { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc };
164 uint64_t offset, size;
166 sfix_write(sfix, bytes);
168 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
169 ptu_ptr(sfix->section);
171 name = pt_section_filename(sfix->section);
172 ptu_str_eq(name, sfix->name);
174 offset = pt_section_offset(sfix->section);
175 ptu_uint_eq(offset, 0x1ull);
177 size = pt_section_size(sfix->section);
178 ptu_uint_eq(size, 0x3ull);
183 static struct ptunit_result create_bad_offset(struct section_fixture *sfix)
185 sfix->section = pt_mk_section(sfix->name, 0x10ull, 0x0ull);
186 ptu_null(sfix->section);
191 static struct ptunit_result create_truncated(struct section_fixture *sfix)
194 uint8_t bytes[] = { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc };
195 uint64_t offset, size;
197 sfix_write(sfix, bytes);
199 sfix->section = pt_mk_section(sfix->name, 0x1ull, UINT64_MAX);
200 ptu_ptr(sfix->section);
202 name = pt_section_filename(sfix->section);
203 ptu_str_eq(name, sfix->name);
205 offset = pt_section_offset(sfix->section);
206 ptu_uint_eq(offset, 0x1ull);
208 size = pt_section_size(sfix->section);
209 ptu_uint_eq(size, sizeof(bytes) - 1);
214 static struct ptunit_result create_empty(struct section_fixture *sfix)
216 sfix->section = pt_mk_section(sfix->name, 0x0ull, 0x10ull);
217 ptu_null(sfix->section);
222 static struct ptunit_result filename_null(void)
226 name = pt_section_filename(NULL);
232 static struct ptunit_result size_null(void)
236 size = pt_section_size(NULL);
237 ptu_uint_eq(size, 0ull);
242 static struct ptunit_result memsize_null(struct section_fixture *sfix)
247 errcode = pt_section_memsize(NULL, &size);
248 ptu_int_eq(errcode, -pte_internal);
250 errcode = pt_section_memsize(sfix->section, NULL);
251 ptu_int_eq(errcode, -pte_internal);
253 errcode = pt_section_memsize(NULL, NULL);
254 ptu_int_eq(errcode, -pte_internal);
259 static struct ptunit_result offset_null(void)
263 offset = pt_section_offset(NULL);
264 ptu_uint_eq(offset, 0ull);
269 static struct ptunit_result get_null(void)
273 errcode = pt_section_get(NULL);
274 ptu_int_eq(errcode, -pte_internal);
279 static struct ptunit_result put_null(void)
283 errcode = pt_section_put(NULL);
284 ptu_int_eq(errcode, -pte_internal);
289 static struct ptunit_result attach_null(void)
291 struct pt_image_section_cache iscache;
292 struct pt_section section;
295 errcode = pt_section_attach(NULL, &iscache);
296 ptu_int_eq(errcode, -pte_internal);
298 errcode = pt_section_attach(§ion, NULL);
299 ptu_int_eq(errcode, -pte_internal);
301 errcode = pt_section_attach(NULL, NULL);
302 ptu_int_eq(errcode, -pte_internal);
307 static struct ptunit_result detach_null(void)
309 struct pt_image_section_cache iscache;
310 struct pt_section section;
313 errcode = pt_section_detach(NULL, &iscache);
314 ptu_int_eq(errcode, -pte_internal);
316 errcode = pt_section_detach(§ion, NULL);
317 ptu_int_eq(errcode, -pte_internal);
319 errcode = pt_section_detach(NULL, NULL);
320 ptu_int_eq(errcode, -pte_internal);
325 static struct ptunit_result map_null(void)
329 errcode = pt_section_map(NULL);
330 ptu_int_eq(errcode, -pte_internal);
335 static struct ptunit_result unmap_null(void)
339 errcode = pt_section_unmap(NULL);
340 ptu_int_eq(errcode, -pte_internal);
345 static struct ptunit_result cache_null(void)
347 struct pt_block_cache *bcache;
349 bcache = pt_section_bcache(NULL);
355 static struct ptunit_result get_overflow(struct section_fixture *sfix)
357 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
360 sfix_write(sfix, bytes);
362 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
363 ptu_ptr(sfix->section);
365 sfix->section->ucount = UINT16_MAX;
367 errcode = pt_section_get(sfix->section);
368 ptu_int_eq(errcode, -pte_overflow);
370 sfix->section->ucount = 1;
375 static struct ptunit_result attach_overflow(struct section_fixture *sfix)
377 struct pt_image_section_cache iscache;
378 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
381 sfix_write(sfix, bytes);
383 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
384 ptu_ptr(sfix->section);
386 sfix->section->acount = UINT16_MAX;
388 errcode = pt_section_attach(sfix->section, &iscache);
389 ptu_int_eq(errcode, -pte_overflow);
391 sfix->section->acount = 0;
396 static struct ptunit_result attach_bad_ucount(struct section_fixture *sfix)
398 struct pt_image_section_cache iscache;
399 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
402 sfix_write(sfix, bytes);
404 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
405 ptu_ptr(sfix->section);
407 sfix->section->acount = 2;
409 errcode = pt_section_attach(sfix->section, &iscache);
410 ptu_int_eq(errcode, -pte_internal);
412 sfix->section->acount = 0;
417 static struct ptunit_result map_change(struct section_fixture *sfix)
419 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
422 sfix_write(sfix, bytes);
424 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
425 ptu_ptr(sfix->section);
427 sfix_write(sfix, bytes);
429 errcode = pt_section_map(sfix->section);
430 ptu_int_eq(errcode, -pte_bad_image);
435 static struct ptunit_result map_put(struct section_fixture *sfix)
437 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
440 sfix_write(sfix, bytes);
442 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
443 ptu_ptr(sfix->section);
445 errcode = pt_section_map(sfix->section);
446 ptu_int_eq(errcode, 0);
448 errcode = pt_section_put(sfix->section);
449 ptu_int_eq(errcode, -pte_internal);
451 errcode = pt_section_unmap(sfix->section);
452 ptu_int_eq(errcode, 0);
457 static struct ptunit_result unmap_nomap(struct section_fixture *sfix)
459 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
462 sfix_write(sfix, bytes);
464 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
465 ptu_ptr(sfix->section);
467 errcode = pt_section_unmap(sfix->section);
468 ptu_int_eq(errcode, -pte_nomap);
473 static struct ptunit_result map_overflow(struct section_fixture *sfix)
475 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
478 sfix_write(sfix, bytes);
480 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
481 ptu_ptr(sfix->section);
483 sfix->section->mcount = UINT16_MAX;
485 errcode = pt_section_map(sfix->section);
486 ptu_int_eq(errcode, -pte_overflow);
488 sfix->section->mcount = 0;
493 static struct ptunit_result get_put(struct section_fixture *sfix)
495 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
498 sfix_write(sfix, bytes);
500 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
501 ptu_ptr(sfix->section);
503 errcode = pt_section_get(sfix->section);
504 ptu_int_eq(errcode, 0);
506 errcode = pt_section_get(sfix->section);
507 ptu_int_eq(errcode, 0);
509 errcode = pt_section_put(sfix->section);
510 ptu_int_eq(errcode, 0);
512 errcode = pt_section_put(sfix->section);
513 ptu_int_eq(errcode, 0);
518 static struct ptunit_result attach_detach(struct section_fixture *sfix)
520 struct pt_image_section_cache iscache;
521 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
524 sfix_write(sfix, bytes);
526 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
527 ptu_ptr(sfix->section);
529 sfix->section->ucount += 2;
531 errcode = pt_section_attach(sfix->section, &iscache);
532 ptu_int_eq(errcode, 0);
534 errcode = pt_section_attach(sfix->section, &iscache);
535 ptu_int_eq(errcode, 0);
537 errcode = pt_section_detach(sfix->section, &iscache);
538 ptu_int_eq(errcode, 0);
540 errcode = pt_section_detach(sfix->section, &iscache);
541 ptu_int_eq(errcode, 0);
543 sfix->section->ucount -= 2;
548 static struct ptunit_result attach_bad_iscache(struct section_fixture *sfix)
550 struct pt_image_section_cache iscache, bad;
551 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
554 sfix_write(sfix, bytes);
556 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
557 ptu_ptr(sfix->section);
559 sfix->section->ucount += 2;
561 errcode = pt_section_attach(sfix->section, &iscache);
562 ptu_int_eq(errcode, 0);
564 errcode = pt_section_attach(sfix->section, &bad);
565 ptu_int_eq(errcode, -pte_internal);
567 errcode = pt_section_detach(sfix->section, &iscache);
568 ptu_int_eq(errcode, 0);
570 sfix->section->ucount -= 2;
575 static struct ptunit_result detach_bad_iscache(struct section_fixture *sfix)
577 struct pt_image_section_cache iscache, bad;
578 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
581 sfix_write(sfix, bytes);
583 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
584 ptu_ptr(sfix->section);
586 errcode = pt_section_attach(sfix->section, &iscache);
587 ptu_int_eq(errcode, 0);
589 errcode = pt_section_detach(sfix->section, &bad);
590 ptu_int_eq(errcode, -pte_internal);
592 errcode = pt_section_detach(sfix->section, &iscache);
593 ptu_int_eq(errcode, 0);
598 static struct ptunit_result map_unmap(struct section_fixture *sfix)
600 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
603 sfix_write(sfix, bytes);
605 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
606 ptu_ptr(sfix->section);
608 errcode = pt_section_map(sfix->section);
609 ptu_int_eq(errcode, 0);
611 errcode = pt_section_map(sfix->section);
612 ptu_int_eq(errcode, 0);
614 errcode = pt_section_unmap(sfix->section);
615 ptu_int_eq(errcode, 0);
617 errcode = pt_section_unmap(sfix->section);
618 ptu_int_eq(errcode, 0);
623 static struct ptunit_result attach_map(struct section_fixture *sfix)
625 struct pt_image_section_cache iscache;
626 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
631 sfix_write(sfix, bytes);
633 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
634 ptu_ptr(sfix->section);
636 errcode = pt_section_attach(sfix->section, &iscache);
637 ptu_int_eq(errcode, 0);
639 errcode = pt_section_map(sfix->section);
640 ptu_int_eq(errcode, 0);
642 errcode = pt_section_map(sfix->section);
643 ptu_int_eq(errcode, 0);
645 ptu_uint_eq(sfix->section->mcount, 2);
647 errcode = pt_section_unmap(sfix->section);
648 ptu_int_eq(errcode, 0);
650 errcode = pt_section_unmap(sfix->section);
651 ptu_int_eq(errcode, 0);
653 errcode = pt_section_detach(sfix->section, &iscache);
654 ptu_int_eq(errcode, 0);
659 static struct ptunit_result attach_bad_map(struct section_fixture *sfix)
661 struct pt_image_section_cache iscache;
662 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
665 iscache.map = -pte_eos;
667 sfix_write(sfix, bytes);
669 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
670 ptu_ptr(sfix->section);
672 errcode = pt_section_attach(sfix->section, &iscache);
673 ptu_int_eq(errcode, 0);
675 errcode = pt_section_map(sfix->section);
676 ptu_int_eq(errcode, -pte_eos);
678 errcode = pt_section_detach(sfix->section, &iscache);
679 ptu_int_eq(errcode, 0);
684 static struct ptunit_result attach_map_overflow(struct section_fixture *sfix)
686 struct pt_image_section_cache iscache;
687 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
692 sfix_write(sfix, bytes);
694 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
695 ptu_ptr(sfix->section);
697 errcode = pt_section_attach(sfix->section, &iscache);
698 ptu_int_eq(errcode, 0);
700 sfix->section->mcount = UINT16_MAX - 1;
702 errcode = pt_section_map(sfix->section);
703 ptu_int_eq(errcode, -pte_overflow);
705 errcode = pt_section_detach(sfix->section, &iscache);
706 ptu_int_eq(errcode, 0);
711 static struct ptunit_result read(struct section_fixture *sfix)
713 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
714 uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
717 sfix_write(sfix, bytes);
719 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
720 ptu_ptr(sfix->section);
722 status = pt_section_map(sfix->section);
723 ptu_int_eq(status, 0);
725 status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
726 ptu_int_eq(status, 2);
727 ptu_uint_eq(buffer[0], bytes[1]);
728 ptu_uint_eq(buffer[1], bytes[2]);
729 ptu_uint_eq(buffer[2], 0xcc);
731 status = pt_section_unmap(sfix->section);
732 ptu_int_eq(status, 0);
737 static struct ptunit_result read_null(struct section_fixture *sfix)
739 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
740 uint8_t buffer[] = { 0xcc };
743 sfix_write(sfix, bytes);
745 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
746 ptu_ptr(sfix->section);
748 status = pt_section_map(sfix->section);
749 ptu_int_eq(status, 0);
751 status = pt_section_read(sfix->section, NULL, 1, 0x0ull);
752 ptu_int_eq(status, -pte_internal);
753 ptu_uint_eq(buffer[0], 0xcc);
755 status = pt_section_read(NULL, buffer, 1, 0x0ull);
756 ptu_int_eq(status, -pte_internal);
757 ptu_uint_eq(buffer[0], 0xcc);
759 status = pt_section_unmap(sfix->section);
760 ptu_int_eq(status, 0);
765 static struct ptunit_result read_offset(struct section_fixture *sfix)
767 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
768 uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
771 sfix_write(sfix, bytes);
773 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
774 ptu_ptr(sfix->section);
776 status = pt_section_map(sfix->section);
777 ptu_int_eq(status, 0);
779 status = pt_section_read(sfix->section, buffer, 2, 0x1ull);
780 ptu_int_eq(status, 2);
781 ptu_uint_eq(buffer[0], bytes[2]);
782 ptu_uint_eq(buffer[1], bytes[3]);
783 ptu_uint_eq(buffer[2], 0xcc);
785 status = pt_section_unmap(sfix->section);
786 ptu_int_eq(status, 0);
791 static struct ptunit_result read_truncated(struct section_fixture *sfix)
793 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc, 0xcc };
796 sfix_write(sfix, bytes);
798 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
799 ptu_ptr(sfix->section);
801 status = pt_section_map(sfix->section);
802 ptu_int_eq(status, 0);
804 status = pt_section_read(sfix->section, buffer, 2, 0x2ull);
805 ptu_int_eq(status, 1);
806 ptu_uint_eq(buffer[0], bytes[3]);
807 ptu_uint_eq(buffer[1], 0xcc);
809 status = pt_section_unmap(sfix->section);
810 ptu_int_eq(status, 0);
815 static struct ptunit_result read_from_truncated(struct section_fixture *sfix)
817 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc, 0xcc };
820 sfix_write(sfix, bytes);
822 sfix->section = pt_mk_section(sfix->name, 0x2ull, 0x10ull);
823 ptu_ptr(sfix->section);
825 status = pt_section_map(sfix->section);
826 ptu_int_eq(status, 0);
828 status = pt_section_read(sfix->section, buffer, 2, 0x1ull);
829 ptu_int_eq(status, 1);
830 ptu_uint_eq(buffer[0], bytes[3]);
831 ptu_uint_eq(buffer[1], 0xcc);
833 status = pt_section_unmap(sfix->section);
834 ptu_int_eq(status, 0);
839 static struct ptunit_result read_nomem(struct section_fixture *sfix)
841 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
844 sfix_write(sfix, bytes);
846 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
847 ptu_ptr(sfix->section);
849 status = pt_section_map(sfix->section);
850 ptu_int_eq(status, 0);
852 status = pt_section_read(sfix->section, buffer, 1, 0x3ull);
853 ptu_int_eq(status, -pte_nomap);
854 ptu_uint_eq(buffer[0], 0xcc);
856 status = pt_section_unmap(sfix->section);
857 ptu_int_eq(status, 0);
862 static struct ptunit_result read_overflow(struct section_fixture *sfix)
864 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
867 sfix_write(sfix, bytes);
869 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
870 ptu_ptr(sfix->section);
872 status = pt_section_map(sfix->section);
873 ptu_int_eq(status, 0);
875 status = pt_section_read(sfix->section, buffer, 1,
876 0xffffffffffff0000ull);
877 ptu_int_eq(status, -pte_nomap);
878 ptu_uint_eq(buffer[0], 0xcc);
880 status = pt_section_unmap(sfix->section);
881 ptu_int_eq(status, 0);
886 static struct ptunit_result read_overflow_32bit(struct section_fixture *sfix)
888 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
891 sfix_write(sfix, bytes);
893 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
894 ptu_ptr(sfix->section);
896 status = pt_section_map(sfix->section);
897 ptu_int_eq(status, 0);
899 status = pt_section_read(sfix->section, buffer, 1,
901 ptu_int_eq(status, -pte_nomap);
902 ptu_uint_eq(buffer[0], 0xcc);
904 status = pt_section_unmap(sfix->section);
905 ptu_int_eq(status, 0);
910 static struct ptunit_result read_nomap(struct section_fixture *sfix)
912 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
915 sfix_write(sfix, bytes);
917 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
918 ptu_ptr(sfix->section);
920 status = pt_section_read(sfix->section, buffer, 1, 0x0ull);
921 ptu_int_eq(status, -pte_nomap);
922 ptu_uint_eq(buffer[0], 0xcc);
927 static struct ptunit_result read_unmap_map(struct section_fixture *sfix)
929 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
930 uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
933 sfix_write(sfix, bytes);
935 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
936 ptu_ptr(sfix->section);
938 status = pt_section_map(sfix->section);
939 ptu_int_eq(status, 0);
941 status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
942 ptu_int_eq(status, 2);
943 ptu_uint_eq(buffer[0], bytes[1]);
944 ptu_uint_eq(buffer[1], bytes[2]);
945 ptu_uint_eq(buffer[2], 0xcc);
947 memset(buffer, 0xcc, sizeof(buffer));
949 status = pt_section_unmap(sfix->section);
950 ptu_int_eq(status, 0);
952 status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
953 ptu_int_eq(status, -pte_nomap);
954 ptu_uint_eq(buffer[0], 0xcc);
955 ptu_uint_eq(buffer[1], 0xcc);
956 ptu_uint_eq(buffer[2], 0xcc);
958 status = pt_section_map(sfix->section);
959 ptu_int_eq(status, 0);
961 status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
962 ptu_int_eq(status, 2);
963 ptu_uint_eq(buffer[0], bytes[1]);
964 ptu_uint_eq(buffer[1], bytes[2]);
965 ptu_uint_eq(buffer[2], 0xcc);
967 status = pt_section_unmap(sfix->section);
968 ptu_int_eq(status, 0);
973 static int worker_read(void *arg)
975 struct section_fixture *sfix;
980 return -pte_internal;
982 for (it = 0; it < num_work; ++it) {
983 uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
986 errcode = pt_section_get(sfix->section);
990 errcode = pt_section_map(sfix->section);
994 read = pt_section_read(sfix->section, buffer, 2, 0x0ull);
998 errcode = -pte_invalid;
999 if ((read != 2) || (buffer[0] != 0x2) || (buffer[1] != 0x4))
1002 errcode = pt_section_unmap(sfix->section);
1006 errcode = pt_section_put(sfix->section);
1014 (void) pt_section_unmap(sfix->section);
1017 (void) pt_section_put(sfix->section);
1021 static int worker_bcache(void *arg)
1023 struct section_fixture *sfix;
1028 return -pte_internal;
1030 errcode = pt_section_get(sfix->section);
1034 for (it = 0; it < num_work; ++it) {
1035 struct pt_block_cache *bcache;
1037 errcode = pt_section_map(sfix->section);
1041 errcode = pt_section_request_bcache(sfix->section);
1045 bcache = pt_section_bcache(sfix->section);
1047 errcode = -pte_nomem;
1051 errcode = pt_section_unmap(sfix->section);
1056 return pt_section_put(sfix->section);
1059 (void) pt_section_unmap(sfix->section);
1062 (void) pt_section_put(sfix->section);
1066 static struct ptunit_result stress(struct section_fixture *sfix,
1067 int (*worker)(void *))
1069 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1072 sfix_write(sfix, bytes);
1074 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1075 ptu_ptr(sfix->section);
1077 #if defined(FEATURE_THREADS)
1081 for (thrd = 0; thrd < num_threads; ++thrd)
1082 ptu_test(ptunit_thrd_create, &sfix->thrd, worker, sfix);
1084 #endif /* defined(FEATURE_THREADS) */
1086 errcode = worker(sfix);
1087 ptu_int_eq(errcode, 0);
1089 return ptu_passed();
1092 static struct ptunit_result init_no_bcache(struct section_fixture *sfix)
1094 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1095 struct pt_block_cache *bcache;
1098 sfix_write(sfix, bytes);
1100 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1101 ptu_ptr(sfix->section);
1103 errcode = pt_section_map(sfix->section);
1104 ptu_int_eq(errcode, 0);
1106 bcache = pt_section_bcache(sfix->section);
1109 errcode = pt_section_unmap(sfix->section);
1110 ptu_int_eq(errcode, 0);
1112 return ptu_passed();
1115 static struct ptunit_result bcache_alloc_free(struct section_fixture *sfix)
1117 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1118 struct pt_block_cache *bcache;
1121 sfix_write(sfix, bytes);
1123 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1124 ptu_ptr(sfix->section);
1126 errcode = pt_section_map(sfix->section);
1127 ptu_int_eq(errcode, 0);
1129 errcode = pt_section_alloc_bcache(sfix->section);
1130 ptu_int_eq(errcode, 0);
1132 bcache = pt_section_bcache(sfix->section);
1134 ptu_uint_eq(bcache->nentries, sfix->section->size);
1136 errcode = pt_section_unmap(sfix->section);
1137 ptu_int_eq(errcode, 0);
1139 bcache = pt_section_bcache(sfix->section);
1142 return ptu_passed();
1145 static struct ptunit_result bcache_alloc_twice(struct section_fixture *sfix)
1147 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1150 sfix_write(sfix, bytes);
1152 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1153 ptu_ptr(sfix->section);
1155 errcode = pt_section_map(sfix->section);
1156 ptu_int_eq(errcode, 0);
1158 errcode = pt_section_alloc_bcache(sfix->section);
1159 ptu_int_eq(errcode, 0);
1161 errcode = pt_section_alloc_bcache(sfix->section);
1162 ptu_int_eq(errcode, 0);
1164 errcode = pt_section_unmap(sfix->section);
1165 ptu_int_eq(errcode, 0);
1167 return ptu_passed();
1170 static struct ptunit_result bcache_alloc_nomap(struct section_fixture *sfix)
1172 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1175 sfix_write(sfix, bytes);
1177 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1178 ptu_ptr(sfix->section);
1180 errcode = pt_section_alloc_bcache(sfix->section);
1181 ptu_int_eq(errcode, -pte_internal);
1183 return ptu_passed();
1186 static struct ptunit_result memsize_nomap(struct section_fixture *sfix)
1189 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1192 sfix_write(sfix, bytes);
1194 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1195 ptu_ptr(sfix->section);
1197 errcode = pt_section_memsize(sfix->section, &memsize);
1198 ptu_int_eq(errcode, 0);
1199 ptu_uint_eq(memsize, 0ull);
1201 return ptu_passed();
1204 static struct ptunit_result memsize_unmap(struct section_fixture *sfix)
1207 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1210 sfix_write(sfix, bytes);
1212 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1213 ptu_ptr(sfix->section);
1215 errcode = pt_section_map(sfix->section);
1216 ptu_int_eq(errcode, 0);
1218 errcode = pt_section_unmap(sfix->section);
1219 ptu_int_eq(errcode, 0);
1221 errcode = pt_section_memsize(sfix->section, &memsize);
1222 ptu_int_eq(errcode, 0);
1223 ptu_uint_eq(memsize, 0ull);
1225 return ptu_passed();
1228 static struct ptunit_result memsize_map_nobcache(struct section_fixture *sfix)
1231 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1234 sfix_write(sfix, bytes);
1236 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1237 ptu_ptr(sfix->section);
1239 errcode = pt_section_map(sfix->section);
1240 ptu_int_eq(errcode, 0);
1242 memsize = 0xfefefefefefefefeull;
1244 errcode = pt_section_memsize(sfix->section, &memsize);
1245 ptu_int_eq(errcode, 0);
1246 ptu_uint_ge(memsize, 0ull);
1247 ptu_uint_le(memsize, 0x2000ull);
1249 errcode = pt_section_unmap(sfix->section);
1250 ptu_int_eq(errcode, 0);
1252 return ptu_passed();
1255 static struct ptunit_result memsize_map_bcache(struct section_fixture *sfix)
1258 uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1261 sfix_write(sfix, bytes);
1263 sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1264 ptu_ptr(sfix->section);
1266 errcode = pt_section_map(sfix->section);
1267 ptu_int_eq(errcode, 0);
1269 errcode = pt_section_alloc_bcache(sfix->section);
1270 ptu_int_eq(errcode, 0);
1272 errcode = pt_section_memsize(sfix->section, &memsize);
1273 ptu_int_eq(errcode, 0);
1274 ptu_uint_ge(memsize,
1275 sfix->section->size * sizeof(struct pt_bcache_entry));
1277 errcode = pt_section_unmap(sfix->section);
1278 ptu_int_eq(errcode, 0);
1280 return ptu_passed();
1283 static struct ptunit_result sfix_init(struct section_fixture *sfix)
1287 sfix->section = NULL;
1291 errcode = ptunit_mkfile(&sfix->file, &sfix->name, "wb");
1292 ptu_int_eq(errcode, 0);
1294 ptu_test(ptunit_thrd_init, &sfix->thrd);
1296 return ptu_passed();
1299 static struct ptunit_result sfix_fini(struct section_fixture *sfix)
1303 ptu_test(ptunit_thrd_fini, &sfix->thrd);
1305 for (thrd = 0; thrd < sfix->thrd.nthreads; ++thrd)
1306 ptu_int_eq(sfix->thrd.result[thrd], 0);
1308 if (sfix->section) {
1309 pt_section_put(sfix->section);
1310 sfix->section = NULL;
1326 return ptu_passed();
1329 int main(int argc, char **argv)
1331 struct section_fixture sfix;
1332 struct ptunit_suite suite;
1334 sfix.init = sfix_init;
1335 sfix.fini = sfix_fini;
1337 suite = ptunit_mk_suite(argc, argv);
1339 ptu_run_f(suite, create, sfix);
1340 ptu_run_f(suite, create_bad_offset, sfix);
1341 ptu_run_f(suite, create_truncated, sfix);
1342 ptu_run_f(suite, create_empty, sfix);
1344 ptu_run(suite, filename_null);
1345 ptu_run(suite, offset_null);
1346 ptu_run(suite, size_null);
1347 ptu_run(suite, get_null);
1348 ptu_run(suite, put_null);
1349 ptu_run(suite, attach_null);
1350 ptu_run(suite, detach_null);
1351 ptu_run(suite, map_null);
1352 ptu_run(suite, unmap_null);
1353 ptu_run(suite, cache_null);
1355 ptu_run_f(suite, get_overflow, sfix);
1356 ptu_run_f(suite, attach_overflow, sfix);
1357 ptu_run_f(suite, attach_bad_ucount, sfix);
1358 ptu_run_f(suite, map_change, sfix);
1359 ptu_run_f(suite, map_put, sfix);
1360 ptu_run_f(suite, unmap_nomap, sfix);
1361 ptu_run_f(suite, map_overflow, sfix);
1362 ptu_run_f(suite, get_put, sfix);
1363 ptu_run_f(suite, attach_detach, sfix);
1364 ptu_run_f(suite, attach_bad_iscache, sfix);
1365 ptu_run_f(suite, detach_bad_iscache, sfix);
1366 ptu_run_f(suite, map_unmap, sfix);
1367 ptu_run_f(suite, attach_map, sfix);
1368 ptu_run_f(suite, attach_bad_map, sfix);
1369 ptu_run_f(suite, attach_map_overflow, sfix);
1370 ptu_run_f(suite, read, sfix);
1371 ptu_run_f(suite, read_null, sfix);
1372 ptu_run_f(suite, read_offset, sfix);
1373 ptu_run_f(suite, read_truncated, sfix);
1374 ptu_run_f(suite, read_from_truncated, sfix);
1375 ptu_run_f(suite, read_nomem, sfix);
1376 ptu_run_f(suite, read_overflow, sfix);
1377 ptu_run_f(suite, read_overflow_32bit, sfix);
1378 ptu_run_f(suite, read_nomap, sfix);
1379 ptu_run_f(suite, read_unmap_map, sfix);
1381 ptu_run_f(suite, init_no_bcache, sfix);
1382 ptu_run_f(suite, bcache_alloc_free, sfix);
1383 ptu_run_f(suite, bcache_alloc_twice, sfix);
1384 ptu_run_f(suite, bcache_alloc_nomap, sfix);
1386 ptu_run_f(suite, memsize_null, sfix);
1387 ptu_run_f(suite, memsize_nomap, sfix);
1388 ptu_run_f(suite, memsize_unmap, sfix);
1389 ptu_run_f(suite, memsize_map_nobcache, sfix);
1390 ptu_run_f(suite, memsize_map_bcache, sfix);
1392 ptu_run_fp(suite, stress, sfix, worker_bcache);
1393 ptu_run_fp(suite, stress, sfix, worker_read);
1395 return ptunit_report(&suite);