xref: /freebsd/contrib/processor-trace/libipt/test/src/ptunit-image.c (revision dd41de95a84d979615a2ef11df6850622bf6184e)
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_image.h"
32 #include "pt_section.h"
33 #include "pt_mapped_section.h"
34 
35 #include "intel-pt.h"
36 
37 
38 struct image_fixture;
39 
40 /* A test mapping. */
41 struct ifix_mapping {
42 	/* The contents. */
43 	uint8_t content[0x10];
44 
45 	/* The size - between 0 and sizeof(content). */
46 	uint64_t size;
47 
48 	/* An artificial error code to be injected into pt_section_read().
49 	 *
50 	 * If @errcode is non-zero, pt_section_read() fails with @errcode.
51 	 */
52 	int errcode;
53 };
54 
55 /* A test file status - turned into a section status. */
56 struct ifix_status {
57 	/* Delete indication:
58 	 * - zero if initialized and not (yet) deleted
59 	 * - non-zero if deleted and not (re-)initialized
60 	 */
61 	int deleted;
62 
63 	/* Put with use-count of zero indication. */
64 	int bad_put;
65 
66 	/* The test mapping to be used. */
67 	struct ifix_mapping *mapping;
68 
69 	/* A link back to the test fixture providing this section. */
70 	struct image_fixture *ifix;
71 };
72 
73 enum {
74 	ifix_nsecs = 5
75 };
76 
77 /* A fake image section cache. */
78 struct pt_image_section_cache {
79 	/* The cached sections. */
80 	struct pt_section *section[ifix_nsecs];
81 
82 	/* Their load addresses. */
83 	uint64_t laddr[ifix_nsecs];
84 
85 	/* The number of used sections. */
86 	int nsecs;
87 };
88 
89 extern int pt_iscache_lookup(struct pt_image_section_cache *iscache,
90 			     struct pt_section **section, uint64_t *laddr,
91 			     int isid);
92 
93 
94 /* A test fixture providing an image, test sections, and asids. */
95 struct image_fixture {
96 	/* The image. */
97 	struct pt_image image;
98 
99 	/* The test states. */
100 	struct ifix_status status[ifix_nsecs];
101 
102 	/* The test mappings. */
103 	struct ifix_mapping mapping[ifix_nsecs];
104 
105 	/* The sections. */
106 	struct pt_section section[ifix_nsecs];
107 
108 	/* The asids. */
109 	struct pt_asid asid[3];
110 
111 	/* The number of used sections/mappings/states. */
112 	int nsecs;
113 
114 	/* An initially empty image as destination for image copies. */
115 	struct pt_image copy;
116 
117 	/* A test section cache. */
118 	struct pt_image_section_cache iscache;
119 
120 	/* The test fixture initialization and finalization functions. */
121 	struct ptunit_result (*init)(struct image_fixture *);
122 	struct ptunit_result (*fini)(struct image_fixture *);
123 };
124 
125 static void ifix_init_section(struct pt_section *section, char *filename,
126 			      struct ifix_status *status,
127 			      struct ifix_mapping *mapping,
128 			      struct image_fixture *ifix)
129 {
130 	uint8_t i;
131 
132 	memset(section, 0, sizeof(*section));
133 
134 	section->filename = filename;
135 	section->status = status;
136 	section->size = mapping->size = sizeof(mapping->content);
137 	section->offset = 0x10;
138 
139 	for (i = 0; i < mapping->size; ++i)
140 		mapping->content[i] = i;
141 
142 	status->deleted = 0;
143 	status->bad_put = 0;
144 	status->mapping = mapping;
145 	status->ifix = ifix;
146 }
147 
148 static int ifix_add_section(struct image_fixture *ifix, char *filename)
149 {
150 	int index;
151 
152 	if (!ifix)
153 		return -pte_internal;
154 
155 	index = ifix->nsecs;
156 	if (ifix_nsecs <= index)
157 		return -pte_internal;
158 
159 	ifix_init_section(&ifix->section[index], filename, &ifix->status[index],
160 			  &ifix->mapping[index], ifix);
161 
162 	ifix->nsecs += 1;
163 	return index;
164 }
165 
166 static int ifix_cache_section(struct image_fixture *ifix,
167 			      struct pt_section *section, uint64_t laddr)
168 {
169 	int index;
170 
171 	if (!ifix)
172 		return -pte_internal;
173 
174 	index = ifix->iscache.nsecs;
175 	if (ifix_nsecs <= index)
176 		return -pte_internal;
177 
178 	ifix->iscache.section[index] = section;
179 	ifix->iscache.laddr[index] = laddr;
180 
181 	index += 1;
182 	ifix->iscache.nsecs = index;
183 
184 	return index;
185 }
186 
187 const char *pt_section_filename(const struct pt_section *section)
188 {
189 	if (!section)
190 		return NULL;
191 
192 	return section->filename;
193 }
194 
195 uint64_t pt_section_offset(const struct pt_section *section)
196 {
197 	if (!section)
198 		return 0ull;
199 
200 	return section->offset;
201 }
202 
203 uint64_t pt_section_size(const struct pt_section *section)
204 {
205 	if (!section)
206 		return 0ull;
207 
208 	return section->size;
209 }
210 
211 int pt_mk_section(struct pt_section **psection, const char *filename,
212 		  uint64_t offset, uint64_t size)
213 {
214 	(void) psection;
215 	(void) filename;
216 	(void) offset;
217 	(void) size;
218 
219 	/* This function is not used by our tests. */
220 	return -pte_not_supported;
221 }
222 
223 int pt_section_get(struct pt_section *section)
224 {
225 	if (!section)
226 		return -pte_internal;
227 
228 	section->ucount += 1;
229 	return 0;
230 }
231 
232 int pt_section_put(struct pt_section *section)
233 {
234 	struct ifix_status *status;
235 	uint16_t ucount;
236 
237 	if (!section)
238 		return -pte_internal;
239 
240 	status = section->status;
241 	if (!status)
242 		return -pte_internal;
243 
244 	ucount = section->ucount;
245 	if (!ucount) {
246 		status->bad_put += 1;
247 
248 		return -pte_internal;
249 	}
250 
251 	ucount = --section->ucount;
252 	if (!ucount) {
253 		status->deleted += 1;
254 
255 		if (status->deleted > 1)
256 			return -pte_internal;
257 	}
258 
259 	return 0;
260 }
261 
262 int pt_iscache_lookup(struct pt_image_section_cache *iscache,
263 		      struct pt_section **section, uint64_t *laddr, int isid)
264 {
265 	if (!iscache || !section || !laddr)
266 		return -pte_internal;
267 
268 	if (!isid || iscache->nsecs < isid)
269 		return -pte_bad_image;
270 
271 	isid -= 1;
272 
273 	*section = iscache->section[isid];
274 	*laddr = iscache->laddr[isid];
275 
276 	return pt_section_get(*section);
277 }
278 
279 static int ifix_unmap(struct pt_section *section)
280 {
281 	uint16_t mcount;
282 
283 	if (!section)
284 		return -pte_internal;
285 
286 	mcount = section->mcount;
287 	if (!mcount)
288 		return -pte_internal;
289 
290 	if (!section->mapping)
291 		return -pte_internal;
292 
293 	mcount = --section->mcount;
294 	if (!mcount)
295 		section->mapping = NULL;
296 
297 	return 0;
298 }
299 
300 static int ifix_read(const struct pt_section *section, uint8_t *buffer,
301 		     uint16_t size, uint64_t offset)
302 {
303 	struct ifix_mapping *mapping;
304 	uint64_t begin, end;
305 
306 	if (!section || !buffer)
307 		return -pte_internal;
308 
309 	begin = offset;
310 	end = begin + size;
311 
312 	if (end < begin)
313 		return -pte_nomap;
314 
315 	mapping = section->mapping;
316 	if (!mapping)
317 		return -pte_nomap;
318 
319 	if (mapping->errcode)
320 		return mapping->errcode;
321 
322 	if (mapping->size <= begin)
323 		return -pte_nomap;
324 
325 	if (mapping->size < end) {
326 		end = mapping->size;
327 		size = (uint16_t) (end - begin);
328 	}
329 
330 	memcpy(buffer, &mapping->content[begin], size);
331 
332 	return size;
333 }
334 
335 int pt_section_map(struct pt_section *section)
336 {
337 	struct ifix_status *status;
338 	uint16_t mcount;
339 
340 	if (!section)
341 		return -pte_internal;
342 
343 	mcount = section->mcount++;
344 	if (mcount)
345 		return 0;
346 
347 	if (section->mapping)
348 		return -pte_internal;
349 
350 	status = section->status;
351 	if (!status)
352 		return -pte_internal;
353 
354 	section->mapping = status->mapping;
355 	section->unmap = ifix_unmap;
356 	section->read = ifix_read;
357 
358 	return 0;
359 }
360 
361 int pt_section_on_map_lock(struct pt_section *section)
362 {
363 	if (!section)
364 		return -pte_internal;
365 
366 	return 0;
367 }
368 
369 int pt_section_unmap(struct pt_section *section)
370 {
371 	if (!section)
372 		return -pte_internal;
373 
374 	if (!section->unmap)
375 		return -pte_nomap;
376 
377 	return section->unmap(section);
378 }
379 
380 int pt_section_read(const struct pt_section *section, uint8_t *buffer,
381 		    uint16_t size, uint64_t offset)
382 {
383 	if (!section)
384 		return -pte_internal;
385 
386 	if (!section->read)
387 		return -pte_nomap;
388 
389 	return section->read(section, buffer, size, offset);
390 }
391 
392 /* A test read memory callback. */
393 static int image_readmem_callback(uint8_t *buffer, size_t size,
394 				  const struct pt_asid *asid,
395 				  uint64_t ip, void *context)
396 {
397 	const uint8_t *memory;
398 	size_t idx;
399 
400 	(void) asid;
401 
402 	if (!buffer)
403 		return -pte_invalid;
404 
405 	/* We use a constant offset of 0x3000. */
406 	if (ip < 0x3000ull)
407 		return -pte_nomap;
408 
409 	ip -= 0x3000ull;
410 
411 	memory = (const uint8_t *) context;
412 	if (!memory)
413 		return -pte_internal;
414 
415 	for (idx = 0; idx < size; ++idx)
416 		buffer[idx] = memory[ip + idx];
417 
418 	return (int) idx;
419 }
420 
421 static struct ptunit_result init(void)
422 {
423 	struct pt_image image;
424 
425 	memset(&image, 0xcd, sizeof(image));
426 
427 	pt_image_init(&image, NULL);
428 	ptu_null(image.name);
429 	ptu_null(image.sections);
430 	ptu_null((void *) (uintptr_t) image.readmem.callback);
431 	ptu_null(image.readmem.context);
432 
433 	return ptu_passed();
434 }
435 
436 static struct ptunit_result init_name(struct image_fixture *ifix)
437 {
438 	memset(&ifix->image, 0xcd, sizeof(ifix->image));
439 
440 	pt_image_init(&ifix->image, "image-name");
441 	ptu_str_eq(ifix->image.name, "image-name");
442 	ptu_null(ifix->image.sections);
443 	ptu_null((void *) (uintptr_t) ifix->image.readmem.callback);
444 	ptu_null(ifix->image.readmem.context);
445 
446 	return ptu_passed();
447 }
448 
449 static struct ptunit_result init_null(void)
450 {
451 	pt_image_init(NULL, NULL);
452 
453 	return ptu_passed();
454 }
455 
456 static struct ptunit_result fini(void)
457 {
458 	struct ifix_mapping mapping;
459 	struct ifix_status status;
460 	struct pt_section section;
461 	struct pt_image image;
462 	struct pt_asid asid;
463 	int errcode;
464 
465 	pt_asid_init(&asid);
466 	ifix_init_section(&section, NULL, &status, &mapping, NULL);
467 
468 	pt_image_init(&image, NULL);
469 	errcode = pt_image_add(&image, &section, &asid, 0x0ull, 0);
470 	ptu_int_eq(errcode, 0);
471 
472 	pt_image_fini(&image);
473 	ptu_int_eq(section.ucount, 0);
474 	ptu_int_eq(section.mcount, 0);
475 	ptu_int_eq(status.deleted, 1);
476 	ptu_int_eq(status.bad_put, 0);
477 
478 	return ptu_passed();
479 }
480 
481 static struct ptunit_result fini_empty(void)
482 {
483 	struct pt_image image;
484 
485 	pt_image_init(&image, NULL);
486 	pt_image_fini(&image);
487 
488 	return ptu_passed();
489 }
490 
491 static struct ptunit_result fini_null(void)
492 {
493 	pt_image_fini(NULL);
494 
495 	return ptu_passed();
496 }
497 
498 static struct ptunit_result name(struct image_fixture *ifix)
499 {
500 	const char *name;
501 
502 	pt_image_init(&ifix->image, "image-name");
503 
504 	name = pt_image_name(&ifix->image);
505 	ptu_str_eq(name, "image-name");
506 
507 	return ptu_passed();
508 }
509 
510 static struct ptunit_result name_none(void)
511 {
512 	struct pt_image image;
513 	const char *name;
514 
515 	pt_image_init(&image, NULL);
516 
517 	name = pt_image_name(&image);
518 	ptu_null(name);
519 
520 	return ptu_passed();
521 }
522 
523 static struct ptunit_result name_null(void)
524 {
525 	const char *name;
526 
527 	name = pt_image_name(NULL);
528 	ptu_null(name);
529 
530 	return ptu_passed();
531 }
532 
533 static struct ptunit_result read_empty(struct image_fixture *ifix)
534 {
535 	struct pt_asid asid;
536 	uint8_t buffer[] = { 0xcc, 0xcc };
537 	int status, isid;
538 
539 	pt_asid_init(&asid);
540 
541 	isid = -1;
542 	status = pt_image_read(&ifix->image, &isid, buffer, sizeof(buffer),
543 			       &asid, 0x1000ull);
544 	ptu_int_eq(status, -pte_nomap);
545 	ptu_int_eq(isid, -1);
546 	ptu_uint_eq(buffer[0], 0xcc);
547 	ptu_uint_eq(buffer[1], 0xcc);
548 
549 	return ptu_passed();
550 }
551 
552 static struct ptunit_result overlap_front(struct image_fixture *ifix)
553 {
554 	uint8_t buffer[] = { 0xcc, 0xcc };
555 	int status, isid;
556 
557 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
558 			      0x1001ull, 1);
559 	ptu_int_eq(status, 0);
560 
561 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[0],
562 			      0x1000ull, 2);
563 	ptu_int_eq(status, 0);
564 
565 	isid = -1;
566 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
567 			       0x1010ull);
568 	ptu_int_eq(status, 1);
569 	ptu_int_eq(isid, 1);
570 	ptu_uint_eq(buffer[0], 0x0f);
571 	ptu_uint_eq(buffer[1], 0xcc);
572 
573 	buffer[0] = 0xcc;
574 
575 	isid = -1;
576 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
577 			       0x100full);
578 	ptu_int_eq(status, 1);
579 	ptu_int_eq(isid, 2);
580 	ptu_uint_eq(buffer[0], 0x0f);
581 	ptu_uint_eq(buffer[1], 0xcc);
582 
583 	return ptu_passed();
584 }
585 
586 static struct ptunit_result overlap_back(struct image_fixture *ifix)
587 {
588 	uint8_t buffer[] = { 0xcc, 0xcc };
589 	int status, isid;
590 
591 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
592 			      0x1000ull, 1);
593 	ptu_int_eq(status, 0);
594 
595 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[0],
596 			      0x1001ull, 2);
597 	ptu_int_eq(status, 0);
598 
599 	isid = -1;
600 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
601 			       0x1000ull);
602 	ptu_int_eq(status, 1);
603 	ptu_int_eq(isid, 1);
604 	ptu_uint_eq(buffer[0], 0x00);
605 	ptu_uint_eq(buffer[1], 0xcc);
606 
607 	isid = -1;
608 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
609 			       0x1010ull);
610 	ptu_int_eq(status, 1);
611 	ptu_int_eq(isid, 2);
612 	ptu_uint_eq(buffer[0], 0x0f);
613 	ptu_uint_eq(buffer[1], 0xcc);
614 
615 	isid = -1;
616 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
617 			       0x1001ull);
618 	ptu_int_eq(status, 1);
619 	ptu_int_eq(isid, 2);
620 	ptu_uint_eq(buffer[0], 0x00);
621 	ptu_uint_eq(buffer[1], 0xcc);
622 
623 	return ptu_passed();
624 }
625 
626 static struct ptunit_result overlap_multiple(struct image_fixture *ifix)
627 {
628 	uint8_t buffer[] = { 0xcc, 0xcc };
629 	int status, isid;
630 
631 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
632 			      0x1000ull, 1);
633 	ptu_int_eq(status, 0);
634 
635 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
636 			      0x1010ull, 2);
637 	ptu_int_eq(status, 0);
638 
639 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
640 			      0x1008ull, 3);
641 	ptu_int_eq(status, 0);
642 
643 	isid = -1;
644 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
645 			       0x1007ull);
646 	ptu_int_eq(status, 1);
647 	ptu_int_eq(isid, 1);
648 	ptu_uint_eq(buffer[0], 0x07);
649 	ptu_uint_eq(buffer[1], 0xcc);
650 
651 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
652 			       0x1008ull);
653 	ptu_int_eq(status, 1);
654 	ptu_int_eq(isid, 3);
655 	ptu_uint_eq(buffer[0], 0x00);
656 	ptu_uint_eq(buffer[1], 0xcc);
657 
658 	isid = -1;
659 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
660 			       0x1017ull);
661 	ptu_int_eq(status, 1);
662 	ptu_int_eq(isid, 3);
663 	ptu_uint_eq(buffer[0], 0x0f);
664 	ptu_uint_eq(buffer[1], 0xcc);
665 
666 	isid = -1;
667 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
668 			       0x1018ull);
669 	ptu_int_eq(status, 1);
670 	ptu_int_eq(isid, 2);
671 	ptu_uint_eq(buffer[0], 0x08);
672 	ptu_uint_eq(buffer[1], 0xcc);
673 
674 	return ptu_passed();
675 }
676 
677 static struct ptunit_result overlap_mid(struct image_fixture *ifix)
678 {
679 	uint8_t buffer[] = { 0xcc, 0xcc };
680 	int status, isid;
681 
682 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
683 			      0x1000ull, 1);
684 	ptu_int_eq(status, 0);
685 
686 	ifix->section[1].size = 0x8;
687 	ifix->mapping[1].size = 0x8;
688 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[0],
689 			      0x1004ull, 2);
690 	ptu_int_eq(status, 0);
691 
692 	isid = -1;
693 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
694 			       0x1003ull);
695 	ptu_int_eq(status, 1);
696 	ptu_int_eq(isid, 1);
697 	ptu_uint_eq(buffer[0], 0x03);
698 	ptu_uint_eq(buffer[1], 0xcc);
699 
700 	isid = -1;
701 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
702 			       0x1004ull);
703 	ptu_int_eq(status, 1);
704 	ptu_int_eq(isid, 2);
705 	ptu_uint_eq(buffer[0], 0x00);
706 	ptu_uint_eq(buffer[1], 0xcc);
707 
708 	isid = -1;
709 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
710 			       0x100bull);
711 	ptu_int_eq(status, 1);
712 	ptu_int_eq(isid, 2);
713 	ptu_uint_eq(buffer[0], 0x07);
714 	ptu_uint_eq(buffer[1], 0xcc);
715 
716 	isid = -1;
717 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
718 			       0x100cull);
719 	ptu_int_eq(status, 1);
720 	ptu_int_eq(isid, 1);
721 	ptu_uint_eq(buffer[0], 0x0c);
722 	ptu_uint_eq(buffer[1], 0xcc);
723 
724 	return ptu_passed();
725 }
726 
727 static struct ptunit_result contained(struct image_fixture *ifix)
728 {
729 	uint8_t buffer[] = { 0xcc, 0xcc };
730 	int status, isid;
731 
732 	ifix->section[0].size = 0x8;
733 	ifix->mapping[0].size = 0x8;
734 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
735 			      0x1004ull, 1);
736 	ptu_int_eq(status, 0);
737 
738 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[0],
739 			      0x1000ull, 2);
740 	ptu_int_eq(status, 0);
741 
742 	isid = -1;
743 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
744 			       0x1008ull);
745 	ptu_int_eq(status, 1);
746 	ptu_int_eq(isid, 2);
747 	ptu_uint_eq(buffer[0], 0x08);
748 	ptu_uint_eq(buffer[1], 0xcc);
749 
750 	return ptu_passed();
751 }
752 
753 static struct ptunit_result contained_multiple(struct image_fixture *ifix)
754 {
755 	uint8_t buffer[] = { 0xcc, 0xcc };
756 	int status, isid;
757 
758 	ifix->section[0].size = 0x2;
759 	ifix->mapping[0].size = 0x2;
760 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
761 			      0x1004ull, 1);
762 	ptu_int_eq(status, 0);
763 
764 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
765 			      0x1008ull, 2);
766 	ptu_int_eq(status, 0);
767 
768 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[0],
769 			      0x1000ull, 3);
770 	ptu_int_eq(status, 0);
771 
772 	isid = -1;
773 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
774 			       0x1004ull);
775 	ptu_int_eq(status, 1);
776 	ptu_int_eq(isid, 3);
777 	ptu_uint_eq(buffer[0], 0x04);
778 	ptu_uint_eq(buffer[1], 0xcc);
779 
780 	isid = -1;
781 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
782 			       0x1008ull);
783 	ptu_int_eq(status, 1);
784 	ptu_int_eq(isid, 3);
785 	ptu_uint_eq(buffer[0], 0x08);
786 	ptu_uint_eq(buffer[1], 0xcc);
787 
788 	return ptu_passed();
789 }
790 
791 static struct ptunit_result contained_back(struct image_fixture *ifix)
792 {
793 	uint8_t buffer[] = { 0xcc, 0xcc };
794 	int status, isid;
795 
796 	ifix->section[0].size = 0x8;
797 	ifix->mapping[0].size = 0x8;
798 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
799 			      0x1004ull, 1);
800 	ptu_int_eq(status, 0);
801 
802 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
803 			      0x100cull, 2);
804 	ptu_int_eq(status, 0);
805 
806 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[0],
807 			      0x1000ull, 3);
808 	ptu_int_eq(status, 0);
809 
810 	isid = -1;
811 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
812 			       0x1004ull);
813 	ptu_int_eq(status, 1);
814 	ptu_int_eq(isid, 3);
815 	ptu_uint_eq(buffer[0], 0x04);
816 	ptu_uint_eq(buffer[1], 0xcc);
817 
818 	isid = -1;
819 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
820 			       0x100cull);
821 	ptu_int_eq(status, 1);
822 	ptu_int_eq(isid, 3);
823 	ptu_uint_eq(buffer[0], 0x0c);
824 	ptu_uint_eq(buffer[1], 0xcc);
825 
826 	isid = -1;
827 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
828 			       0x100full);
829 	ptu_int_eq(status, 1);
830 	ptu_int_eq(isid, 3);
831 	ptu_uint_eq(buffer[0], 0x0f);
832 	ptu_uint_eq(buffer[1], 0xcc);
833 
834 	isid = -1;
835 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
836 			       0x1010ull);
837 	ptu_int_eq(status, 1);
838 	ptu_int_eq(isid, 2);
839 	ptu_uint_eq(buffer[0], 0x04);
840 	ptu_uint_eq(buffer[1], 0xcc);
841 
842 	return ptu_passed();
843 }
844 
845 static struct ptunit_result same(struct image_fixture *ifix)
846 {
847 	uint8_t buffer[] = { 0xcc, 0xcc };
848 	int status, isid;
849 
850 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
851 			      0x1000ull, 1);
852 	ptu_int_eq(status, 0);
853 
854 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
855 			      0x1000ull, 1);
856 	ptu_int_eq(status, 0);
857 
858 	isid = -1;
859 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
860 			       0x1008ull);
861 	ptu_int_eq(status, 1);
862 	ptu_int_eq(isid, 1);
863 	ptu_uint_eq(buffer[0], 0x08);
864 	ptu_uint_eq(buffer[1], 0xcc);
865 
866 	return ptu_passed();
867 }
868 
869 static struct ptunit_result same_different_isid(struct image_fixture *ifix)
870 {
871 	uint8_t buffer[] = { 0xcc, 0xcc };
872 	int status, isid;
873 
874 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
875 			      0x1000ull, 1);
876 	ptu_int_eq(status, 0);
877 
878 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
879 			      0x1000ull, 2);
880 	ptu_int_eq(status, 0);
881 
882 	isid = -1;
883 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
884 			       0x1008ull);
885 	ptu_int_eq(status, 1);
886 	ptu_int_eq(isid, 2);
887 	ptu_uint_eq(buffer[0], 0x08);
888 	ptu_uint_eq(buffer[1], 0xcc);
889 
890 	return ptu_passed();
891 }
892 
893 static struct ptunit_result same_different_offset(struct image_fixture *ifix)
894 {
895 	uint8_t buffer[] = { 0xcc, 0xcc }, i;
896 	int status, isid, index;
897 
898 	/* Add another section from a different part of the same file as an
899 	 * existing section.
900 	 */
901 	index = ifix_add_section(ifix, ifix->section[0].filename);
902 	ptu_int_gt(index, 0);
903 
904 	ifix->section[index].offset = ifix->section[0].offset + 0x10;
905 	ptu_uint_eq(ifix->section[index].size, ifix->section[0].size);
906 
907 	/* Change the content of the new section so we can distinguish them. */
908 	for (i = 0; i < ifix->mapping[index].size; ++i)
909 		ifix->mapping[index].content[i] += 0x10;
910 
911 
912 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
913 			      0x1000ull, 0);
914 	ptu_int_eq(status, 0);
915 
916 	status = pt_image_add(&ifix->image, &ifix->section[index],
917 			      &ifix->asid[0], 0x1000ull, 0);
918 	ptu_int_eq(status, 0);
919 
920 	isid = -1;
921 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
922 			       0x1000ull);
923 	ptu_int_eq(status, 1);
924 	ptu_int_eq(isid, 0);
925 	ptu_uint_eq(buffer[0], 0x10);
926 	ptu_uint_eq(buffer[1], 0xcc);
927 
928 	isid = -1;
929 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
930 			       0x100full);
931 	ptu_int_eq(status, 1);
932 	ptu_int_eq(isid, 0);
933 	ptu_uint_eq(buffer[0], 0x1f);
934 	ptu_uint_eq(buffer[1], 0xcc);
935 
936 	return ptu_passed();
937 }
938 
939 static struct ptunit_result adjacent(struct image_fixture *ifix)
940 {
941 	uint8_t buffer[] = { 0xcc, 0xcc };
942 	int status, isid;
943 
944 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
945 			      0x1000ull, 1);
946 	ptu_int_eq(status, 0);
947 
948 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[0],
949 			      0x1000ull - ifix->section[1].size, 2);
950 	ptu_int_eq(status, 0);
951 
952 	status = pt_image_add(&ifix->image, &ifix->section[2], &ifix->asid[0],
953 			      0x1000ull + ifix->section[0].size, 3);
954 	ptu_int_eq(status, 0);
955 
956 	isid = -1;
957 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
958 			       0x1000ull);
959 	ptu_int_eq(status, 1);
960 	ptu_int_eq(isid, 1);
961 	ptu_uint_eq(buffer[0], 0x00);
962 	ptu_uint_eq(buffer[1], 0xcc);
963 
964 	isid = -1;
965 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
966 			       0xfffull);
967 	ptu_int_eq(status, 1);
968 	ptu_int_eq(isid, 2);
969 	ptu_uint_eq(buffer[0],
970 		    ifix->mapping[1].content[ifix->mapping[1].size - 1]);
971 	ptu_uint_eq(buffer[1], 0xcc);
972 
973 	isid = -1;
974 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
975 			       0x1000ull + ifix->section[0].size);
976 	ptu_int_eq(status, 1);
977 	ptu_int_eq(isid, 3);
978 	ptu_uint_eq(buffer[0], 0x00);
979 	ptu_uint_eq(buffer[1], 0xcc);
980 
981 	return ptu_passed();
982 }
983 
984 static struct ptunit_result read_null(struct image_fixture *ifix)
985 {
986 	uint8_t buffer;
987 	int status, isid;
988 
989 	status = pt_image_read(NULL, &isid, &buffer, 1, &ifix->asid[0],
990 			       0x1000ull);
991 	ptu_int_eq(status, -pte_internal);
992 
993 	status = pt_image_read(&ifix->image, NULL, &buffer, 1, &ifix->asid[0],
994 			       0x1000ull);
995 	ptu_int_eq(status, -pte_internal);
996 
997 	status = pt_image_read(&ifix->image, &isid, NULL, 1, &ifix->asid[0],
998 			       0x1000ull);
999 	ptu_int_eq(status, -pte_internal);
1000 
1001 	status = pt_image_read(&ifix->image, &isid, &buffer, 1, NULL,
1002 			       0x1000ull);
1003 	ptu_int_eq(status, -pte_internal);
1004 
1005 	return ptu_passed();
1006 }
1007 
1008 static struct ptunit_result read(struct image_fixture *ifix)
1009 {
1010 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1011 	int status, isid;
1012 
1013 	isid = -1;
1014 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[1],
1015 			       0x2003ull);
1016 	ptu_int_eq(status, 2);
1017 	ptu_int_eq(isid, 11);
1018 	ptu_uint_eq(buffer[0], 0x03);
1019 	ptu_uint_eq(buffer[1], 0x04);
1020 	ptu_uint_eq(buffer[2], 0xcc);
1021 
1022 	return ptu_passed();
1023 }
1024 
1025 static struct ptunit_result read_asid(struct image_fixture *ifix)
1026 {
1027 	uint8_t buffer[] = { 0xcc, 0xcc };
1028 	int status, isid;
1029 
1030 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
1031 			      0x1000ull, 1);
1032 	ptu_int_eq(status, 0);
1033 
1034 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[1],
1035 			      0x1008ull, 2);
1036 	ptu_int_eq(status, 0);
1037 
1038 	isid = -1;
1039 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
1040 			       0x1009ull);
1041 	ptu_int_eq(status, 1);
1042 	ptu_int_eq(isid, 1);
1043 	ptu_uint_eq(buffer[0], 0x09);
1044 	ptu_uint_eq(buffer[1], 0xcc);
1045 
1046 	isid = -1;
1047 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[1],
1048 			       0x1009ull);
1049 	ptu_int_eq(status, 1);
1050 	ptu_int_eq(isid, 2);
1051 	ptu_uint_eq(buffer[0], 0x01);
1052 	ptu_uint_eq(buffer[1], 0xcc);
1053 
1054 	return ptu_passed();
1055 }
1056 
1057 static struct ptunit_result read_bad_asid(struct image_fixture *ifix)
1058 {
1059 	uint8_t buffer[] = { 0xcc, 0xcc };
1060 	int status, isid;
1061 
1062 	isid = -1;
1063 	status = pt_image_read(&ifix->image, &isid, buffer, sizeof(buffer),
1064 			       &ifix->asid[0], 0x2003ull);
1065 	ptu_int_eq(status, -pte_nomap);
1066 	ptu_int_eq(isid, -1);
1067 	ptu_uint_eq(buffer[0], 0xcc);
1068 	ptu_uint_eq(buffer[1], 0xcc);
1069 
1070 	return ptu_passed();
1071 }
1072 
1073 static struct ptunit_result read_null_asid(struct image_fixture *ifix)
1074 {
1075 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1076 	int status, isid;
1077 
1078 	isid = -1;
1079 	status = pt_image_read(&ifix->image, &isid, buffer, 2, NULL, 0x2003ull);
1080 	ptu_int_eq(status, -pte_internal);
1081 	ptu_int_eq(isid, -1);
1082 	ptu_uint_eq(buffer[0], 0xcc);
1083 	ptu_uint_eq(buffer[1], 0xcc);
1084 
1085 	return ptu_passed();
1086 }
1087 
1088 static struct ptunit_result read_callback(struct image_fixture *ifix)
1089 {
1090 	uint8_t memory[] = { 0xdd, 0x01, 0x02, 0xdd };
1091 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1092 	int status, isid;
1093 
1094 	status = pt_image_set_callback(&ifix->image, image_readmem_callback,
1095 				       memory);
1096 	ptu_int_eq(status, 0);
1097 
1098 	isid = -1;
1099 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1100 			       0x3001ull);
1101 	ptu_int_eq(status, 2);
1102 	ptu_int_eq(isid, 0);
1103 	ptu_uint_eq(buffer[0], 0x01);
1104 	ptu_uint_eq(buffer[1], 0x02);
1105 	ptu_uint_eq(buffer[2], 0xcc);
1106 
1107 	return ptu_passed();
1108 }
1109 
1110 static struct ptunit_result read_nomem(struct image_fixture *ifix)
1111 {
1112 	uint8_t buffer[] = { 0xcc, 0xcc };
1113 	int status, isid;
1114 
1115 	isid = -1;
1116 	status = pt_image_read(&ifix->image, &isid, buffer, sizeof(buffer),
1117 			       &ifix->asid[1], 0x1010ull);
1118 	ptu_int_eq(status, -pte_nomap);
1119 	ptu_int_eq(isid, -1);
1120 	ptu_uint_eq(buffer[0], 0xcc);
1121 	ptu_uint_eq(buffer[1], 0xcc);
1122 
1123 	return ptu_passed();
1124 }
1125 
1126 static struct ptunit_result read_truncated(struct image_fixture *ifix)
1127 {
1128 	uint8_t buffer[] = { 0xcc, 0xcc };
1129 	int status, isid;
1130 
1131 	isid = -1;
1132 	status = pt_image_read(&ifix->image, &isid, buffer, sizeof(buffer),
1133 			       &ifix->asid[0], 0x100full);
1134 	ptu_int_eq(status, 1);
1135 	ptu_int_eq(isid, 10);
1136 	ptu_uint_eq(buffer[0], 0x0f);
1137 	ptu_uint_eq(buffer[1], 0xcc);
1138 
1139 	return ptu_passed();
1140 }
1141 
1142 static struct ptunit_result read_error(struct image_fixture *ifix)
1143 {
1144 	uint8_t buffer[] = { 0xcc };
1145 	int status, isid;
1146 
1147 	ifix->mapping[0].errcode = -pte_nosync;
1148 
1149 	isid = -1;
1150 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
1151 			       0x1000ull);
1152 	ptu_int_eq(status, -pte_nosync);
1153 	ptu_int_eq(isid, 10);
1154 	ptu_uint_eq(buffer[0], 0xcc);
1155 
1156 	return ptu_passed();
1157 }
1158 
1159 static struct ptunit_result read_spurious_error(struct image_fixture *ifix)
1160 {
1161 	uint8_t buffer[] = { 0xcc, 0xcc };
1162 	int status, isid;
1163 
1164 	isid = -1;
1165 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
1166 			       0x1000ull);
1167 	ptu_int_eq(status, 1);
1168 	ptu_int_eq(isid, 10);
1169 	ptu_uint_eq(buffer[0], 0x00);
1170 	ptu_uint_eq(buffer[1], 0xcc);
1171 
1172 	ifix->mapping[0].errcode = -pte_nosync;
1173 
1174 	isid = -1;
1175 	status = pt_image_read(&ifix->image, &isid, buffer, 1, &ifix->asid[0],
1176 			       0x1005ull);
1177 	ptu_int_eq(status, -pte_nosync);
1178 	ptu_int_eq(isid, 10);
1179 	ptu_uint_eq(buffer[0], 0x00);
1180 
1181 	return ptu_passed();
1182 }
1183 
1184 static struct ptunit_result remove_section(struct image_fixture *ifix)
1185 {
1186 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1187 	int status, isid;
1188 
1189 	isid = -1;
1190 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1191 			       0x1001ull);
1192 	ptu_int_eq(status, 2);
1193 	ptu_int_eq(isid, 10);
1194 	ptu_uint_eq(buffer[0], 0x01);
1195 	ptu_uint_eq(buffer[1], 0x02);
1196 	ptu_uint_eq(buffer[2], 0xcc);
1197 
1198 	status = pt_image_remove(&ifix->image, &ifix->section[0],
1199 				 &ifix->asid[0], 0x1000ull);
1200 	ptu_int_eq(status, 0);
1201 
1202 	ptu_int_ne(ifix->status[0].deleted, 0);
1203 	ptu_int_eq(ifix->status[1].deleted, 0);
1204 
1205 	isid = -1;
1206 	status = pt_image_read(&ifix->image, &isid, buffer, sizeof(buffer),
1207 			       &ifix->asid[0], 0x1003ull);
1208 	ptu_int_eq(status, -pte_nomap);
1209 	ptu_int_eq(isid, -1);
1210 	ptu_uint_eq(buffer[0], 0x01);
1211 	ptu_uint_eq(buffer[1], 0x02);
1212 	ptu_uint_eq(buffer[2], 0xcc);
1213 
1214 	isid = -1;
1215 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[1],
1216 			       0x2003ull);
1217 	ptu_int_eq(status, 2);
1218 	ptu_int_eq(isid, 11);
1219 	ptu_uint_eq(buffer[0], 0x03);
1220 	ptu_uint_eq(buffer[1], 0x04);
1221 	ptu_uint_eq(buffer[2], 0xcc);
1222 
1223 	return ptu_passed();
1224 }
1225 
1226 static struct ptunit_result remove_bad_vaddr(struct image_fixture *ifix)
1227 {
1228 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1229 	int status, isid;
1230 
1231 	isid = -1;
1232 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1233 			       0x1001ull);
1234 	ptu_int_eq(status, 2);
1235 	ptu_int_eq(isid, 10);
1236 	ptu_uint_eq(buffer[0], 0x01);
1237 	ptu_uint_eq(buffer[1], 0x02);
1238 	ptu_uint_eq(buffer[2], 0xcc);
1239 
1240 	status = pt_image_remove(&ifix->image, &ifix->section[0],
1241 				 &ifix->asid[0], 0x2000ull);
1242 	ptu_int_eq(status, -pte_bad_image);
1243 
1244 	ptu_int_eq(ifix->status[0].deleted, 0);
1245 	ptu_int_eq(ifix->status[1].deleted, 0);
1246 
1247 	isid = -1;
1248 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1249 			       0x1003ull);
1250 	ptu_int_eq(status, 2);
1251 	ptu_int_eq(isid, 10);
1252 	ptu_uint_eq(buffer[0], 0x03);
1253 	ptu_uint_eq(buffer[1], 0x04);
1254 	ptu_uint_eq(buffer[2], 0xcc);
1255 
1256 	isid = -1;
1257 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[1],
1258 			       0x2005ull);
1259 	ptu_int_eq(status, 2);
1260 	ptu_int_eq(isid, 11);
1261 	ptu_uint_eq(buffer[0], 0x05);
1262 	ptu_uint_eq(buffer[1], 0x06);
1263 	ptu_uint_eq(buffer[2], 0xcc);
1264 
1265 	return ptu_passed();
1266 }
1267 
1268 static struct ptunit_result remove_bad_asid(struct image_fixture *ifix)
1269 {
1270 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1271 	int status, isid;
1272 
1273 	isid = -1;
1274 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1275 			       0x1001ull);
1276 	ptu_int_eq(status, 2);
1277 	ptu_int_eq(isid, 10);
1278 	ptu_uint_eq(buffer[0], 0x01);
1279 	ptu_uint_eq(buffer[1], 0x02);
1280 	ptu_uint_eq(buffer[2], 0xcc);
1281 
1282 	status = pt_image_remove(&ifix->image, &ifix->section[0],
1283 				 &ifix->asid[1], 0x1000ull);
1284 	ptu_int_eq(status, -pte_bad_image);
1285 
1286 	ptu_int_eq(ifix->status[0].deleted, 0);
1287 	ptu_int_eq(ifix->status[1].deleted, 0);
1288 
1289 	isid = -1;
1290 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1291 			       0x1003ull);
1292 	ptu_int_eq(status, 2);
1293 	ptu_int_eq(isid, 10);
1294 	ptu_uint_eq(buffer[0], 0x03);
1295 	ptu_uint_eq(buffer[1], 0x04);
1296 	ptu_uint_eq(buffer[2], 0xcc);
1297 
1298 	isid = -1;
1299 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[1],
1300 			       0x2005ull);
1301 	ptu_int_eq(status, 2);
1302 	ptu_int_eq(isid, 11);
1303 	ptu_uint_eq(buffer[0], 0x05);
1304 	ptu_uint_eq(buffer[1], 0x06);
1305 	ptu_uint_eq(buffer[2], 0xcc);
1306 
1307 	return ptu_passed();
1308 }
1309 
1310 static struct ptunit_result remove_by_filename(struct image_fixture *ifix)
1311 {
1312 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1313 	int status, isid;
1314 
1315 	isid = -1;
1316 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1317 			       0x1001ull);
1318 	ptu_int_eq(status, 2);
1319 	ptu_int_eq(isid, 10);
1320 	ptu_uint_eq(buffer[0], 0x01);
1321 	ptu_uint_eq(buffer[1], 0x02);
1322 	ptu_uint_eq(buffer[2], 0xcc);
1323 
1324 	status = pt_image_remove_by_filename(&ifix->image,
1325 					     ifix->section[0].filename,
1326 					     &ifix->asid[0]);
1327 	ptu_int_eq(status, 1);
1328 
1329 	ptu_int_ne(ifix->status[0].deleted, 0);
1330 	ptu_int_eq(ifix->status[1].deleted, 0);
1331 
1332 	isid = -1;
1333 	status = pt_image_read(&ifix->image, &isid, buffer, sizeof(buffer),
1334 			       &ifix->asid[0], 0x1003ull);
1335 	ptu_int_eq(status, -pte_nomap);
1336 	ptu_int_eq(isid, -1);
1337 	ptu_uint_eq(buffer[0], 0x01);
1338 	ptu_uint_eq(buffer[1], 0x02);
1339 	ptu_uint_eq(buffer[2], 0xcc);
1340 
1341 	isid = -1;
1342 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[1],
1343 			       0x2003ull);
1344 	ptu_int_eq(status, 2);
1345 	ptu_int_eq(isid, 11);
1346 	ptu_uint_eq(buffer[0], 0x03);
1347 	ptu_uint_eq(buffer[1], 0x04);
1348 	ptu_uint_eq(buffer[2], 0xcc);
1349 
1350 	return ptu_passed();
1351 }
1352 
1353 static struct ptunit_result
1354 remove_by_filename_bad_asid(struct image_fixture *ifix)
1355 {
1356 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1357 	int status, isid;
1358 
1359 	isid = -1;
1360 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1361 			       0x1001ull);
1362 	ptu_int_eq(status, 2);
1363 	ptu_int_eq(isid, 10);
1364 	ptu_uint_eq(buffer[0], 0x01);
1365 	ptu_uint_eq(buffer[1], 0x02);
1366 	ptu_uint_eq(buffer[2], 0xcc);
1367 
1368 	status = pt_image_remove_by_filename(&ifix->image,
1369 					     ifix->section[0].filename,
1370 					     &ifix->asid[1]);
1371 	ptu_int_eq(status, 0);
1372 
1373 	ptu_int_eq(ifix->status[0].deleted, 0);
1374 	ptu_int_eq(ifix->status[1].deleted, 0);
1375 
1376 	isid = -1;
1377 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1378 			       0x1003ull);
1379 	ptu_int_eq(status, 2);
1380 	ptu_int_eq(isid, 10);
1381 	ptu_uint_eq(buffer[0], 0x03);
1382 	ptu_uint_eq(buffer[1], 0x04);
1383 	ptu_uint_eq(buffer[2], 0xcc);
1384 
1385 	isid = -1;
1386 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[1],
1387 			       0x2005ull);
1388 	ptu_int_eq(status, 2);
1389 	ptu_int_eq(isid, 11);
1390 	ptu_uint_eq(buffer[0], 0x05);
1391 	ptu_uint_eq(buffer[1], 0x06);
1392 	ptu_uint_eq(buffer[2], 0xcc);
1393 
1394 	return ptu_passed();
1395 }
1396 
1397 static struct ptunit_result remove_none_by_filename(struct image_fixture *ifix)
1398 {
1399 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1400 	int status, isid;
1401 
1402 	status = pt_image_remove_by_filename(&ifix->image, "bad-name",
1403 					     &ifix->asid[0]);
1404 	ptu_int_eq(status, 0);
1405 
1406 	ptu_int_eq(ifix->status[0].deleted, 0);
1407 	ptu_int_eq(ifix->status[1].deleted, 0);
1408 
1409 	isid = -1;
1410 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1411 			       0x1003ull);
1412 	ptu_int_eq(status, 2);
1413 	ptu_int_eq(isid, 10);
1414 	ptu_uint_eq(buffer[0], 0x03);
1415 	ptu_uint_eq(buffer[1], 0x04);
1416 	ptu_uint_eq(buffer[2], 0xcc);
1417 
1418 	isid = -1;
1419 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[1],
1420 			       0x2001ull);
1421 	ptu_int_eq(status, 2);
1422 	ptu_int_eq(isid, 11);
1423 	ptu_uint_eq(buffer[0], 0x01);
1424 	ptu_uint_eq(buffer[1], 0x02);
1425 	ptu_uint_eq(buffer[2], 0xcc);
1426 
1427 	return ptu_passed();
1428 }
1429 
1430 static struct ptunit_result remove_all_by_filename(struct image_fixture *ifix)
1431 {
1432 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1433 	int status, isid;
1434 
1435 	ifix->section[0].filename = "same-name";
1436 	ifix->section[1].filename = "same-name";
1437 
1438 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
1439 			      0x1000ull, 1);
1440 	ptu_int_eq(status, 0);
1441 
1442 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[0],
1443 			      0x2000ull, 2);
1444 	ptu_int_eq(status, 0);
1445 
1446 	isid = -1;
1447 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1448 			       0x1001ull);
1449 	ptu_int_eq(status, 2);
1450 	ptu_int_eq(isid, 1);
1451 	ptu_uint_eq(buffer[0], 0x01);
1452 	ptu_uint_eq(buffer[1], 0x02);
1453 	ptu_uint_eq(buffer[2], 0xcc);
1454 
1455 	status = pt_image_remove_by_filename(&ifix->image, "same-name",
1456 					     &ifix->asid[0]);
1457 	ptu_int_eq(status, 2);
1458 
1459 	ptu_int_ne(ifix->status[0].deleted, 0);
1460 	ptu_int_ne(ifix->status[1].deleted, 0);
1461 
1462 	isid = -1;
1463 	status = pt_image_read(&ifix->image, &isid, buffer, sizeof(buffer),
1464 			       &ifix->asid[0], 0x1003ull);
1465 	ptu_int_eq(status, -pte_nomap);
1466 	ptu_int_eq(isid, -1);
1467 	ptu_uint_eq(buffer[0], 0x01);
1468 	ptu_uint_eq(buffer[1], 0x02);
1469 	ptu_uint_eq(buffer[2], 0xcc);
1470 
1471 	isid = -1;
1472 	status = pt_image_read(&ifix->image, &isid, buffer, sizeof(buffer),
1473 			       &ifix->asid[0], 0x2003ull);
1474 	ptu_int_eq(status, -pte_nomap);
1475 	ptu_int_eq(isid, -1);
1476 	ptu_uint_eq(buffer[0], 0x01);
1477 	ptu_uint_eq(buffer[1], 0x02);
1478 	ptu_uint_eq(buffer[2], 0xcc);
1479 
1480 	return ptu_passed();
1481 }
1482 
1483 static struct ptunit_result remove_by_asid(struct image_fixture *ifix)
1484 {
1485 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1486 	int status, isid;
1487 
1488 	isid = -1;
1489 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1490 			       0x1001ull);
1491 	ptu_int_eq(status, 2);
1492 	ptu_int_eq(isid, 10);
1493 	ptu_uint_eq(buffer[0], 0x01);
1494 	ptu_uint_eq(buffer[1], 0x02);
1495 	ptu_uint_eq(buffer[2], 0xcc);
1496 
1497 	status = pt_image_remove_by_asid(&ifix->image, &ifix->asid[0]);
1498 	ptu_int_eq(status, 1);
1499 
1500 	ptu_int_ne(ifix->status[0].deleted, 0);
1501 	ptu_int_eq(ifix->status[1].deleted, 0);
1502 
1503 	isid = -1;
1504 	status = pt_image_read(&ifix->image, &isid, buffer, sizeof(buffer),
1505 			       &ifix->asid[0], 0x1003ull);
1506 	ptu_int_eq(status, -pte_nomap);
1507 	ptu_int_eq(isid, -1);
1508 	ptu_uint_eq(buffer[0], 0x01);
1509 	ptu_uint_eq(buffer[1], 0x02);
1510 	ptu_uint_eq(buffer[2], 0xcc);
1511 
1512 	isid = -1;
1513 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[1],
1514 			       0x2003ull);
1515 	ptu_int_eq(status, 2);
1516 	ptu_int_eq(isid, 11);
1517 	ptu_uint_eq(buffer[0], 0x03);
1518 	ptu_uint_eq(buffer[1], 0x04);
1519 	ptu_uint_eq(buffer[2], 0xcc);
1520 
1521 	return ptu_passed();
1522 }
1523 
1524 static struct ptunit_result copy_empty(struct image_fixture *ifix)
1525 {
1526 	struct pt_asid asid;
1527 	uint8_t buffer[] = { 0xcc, 0xcc };
1528 	int status, isid;
1529 
1530 	pt_asid_init(&asid);
1531 
1532 	status = pt_image_copy(&ifix->copy, &ifix->image);
1533 	ptu_int_eq(status, 0);
1534 
1535 	isid = -1;
1536 	status = pt_image_read(&ifix->copy, &isid, buffer, sizeof(buffer),
1537 			       &asid, 0x1000ull);
1538 	ptu_int_eq(status, -pte_nomap);
1539 	ptu_int_eq(isid, -1);
1540 	ptu_uint_eq(buffer[0], 0xcc);
1541 	ptu_uint_eq(buffer[1], 0xcc);
1542 
1543 	return ptu_passed();
1544 }
1545 
1546 static struct ptunit_result copy(struct image_fixture *ifix)
1547 {
1548 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1549 	int status, isid;
1550 
1551 	status = pt_image_copy(&ifix->copy, &ifix->image);
1552 	ptu_int_eq(status, 0);
1553 
1554 	isid = -1;
1555 	status = pt_image_read(&ifix->copy, &isid, buffer, 2, &ifix->asid[1],
1556 			       0x2003ull);
1557 	ptu_int_eq(status, 2);
1558 	ptu_int_eq(isid, 11);
1559 	ptu_uint_eq(buffer[0], 0x03);
1560 	ptu_uint_eq(buffer[1], 0x04);
1561 	ptu_uint_eq(buffer[2], 0xcc);
1562 
1563 	return ptu_passed();
1564 }
1565 
1566 static struct ptunit_result copy_self(struct image_fixture *ifix)
1567 {
1568 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1569 	int status, isid;
1570 
1571 	status = pt_image_copy(&ifix->image, &ifix->image);
1572 	ptu_int_eq(status, 0);
1573 
1574 	isid = -1;
1575 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[1],
1576 			       0x2003ull);
1577 	ptu_int_eq(status, 2);
1578 	ptu_int_eq(isid, 11);
1579 	ptu_uint_eq(buffer[0], 0x03);
1580 	ptu_uint_eq(buffer[1], 0x04);
1581 	ptu_uint_eq(buffer[2], 0xcc);
1582 
1583 	return ptu_passed();
1584 }
1585 
1586 static struct ptunit_result copy_shrink(struct image_fixture *ifix)
1587 {
1588 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1589 	int status, isid;
1590 
1591 	status = pt_image_add(&ifix->copy, &ifix->section[1], &ifix->asid[1],
1592 			      0x2000ull, 1);
1593 	ptu_int_eq(status, 0);
1594 
1595 	status = pt_image_copy(&ifix->copy, &ifix->image);
1596 	ptu_int_eq(status, 0);
1597 
1598 	isid = -1;
1599 	status = pt_image_read(&ifix->copy, &isid, buffer, 2, &ifix->asid[1],
1600 			       0x2003ull);
1601 	ptu_int_eq(status, 2);
1602 	ptu_int_eq(isid, 11);
1603 	ptu_uint_eq(buffer[0], 0x03);
1604 	ptu_uint_eq(buffer[1], 0x04);
1605 	ptu_uint_eq(buffer[2], 0xcc);
1606 
1607 	return ptu_passed();
1608 }
1609 
1610 static struct ptunit_result copy_split(struct image_fixture *ifix)
1611 {
1612 	uint8_t buffer[] = { 0xcc, 0xcc };
1613 	int status, isid;
1614 
1615 	status = pt_image_add(&ifix->copy, &ifix->section[0], &ifix->asid[0],
1616 			      0x2000ull, 1);
1617 	ptu_int_eq(status, 0);
1618 
1619 	ifix->section[1].size = 0x7;
1620 	ifix->mapping[1].size = 0x7;
1621 
1622 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[0],
1623 			      0x2001ull, 2);
1624 	ptu_int_eq(status, 0);
1625 
1626 	ifix->section[2].size = 0x8;
1627 	ifix->mapping[2].size = 0x8;
1628 
1629 	status = pt_image_add(&ifix->image, &ifix->section[2], &ifix->asid[0],
1630 			      0x2008ull, 3);
1631 	ptu_int_eq(status, 0);
1632 
1633 	status = pt_image_copy(&ifix->copy, &ifix->image);
1634 	ptu_int_eq(status, 0);
1635 
1636 	isid = -1;
1637 	status = pt_image_read(&ifix->copy, &isid, buffer, 1, &ifix->asid[0],
1638 			       0x2003ull);
1639 	ptu_int_eq(status, 1);
1640 	ptu_int_eq(isid, 2);
1641 	ptu_uint_eq(buffer[0], 0x02);
1642 	ptu_uint_eq(buffer[1], 0xcc);
1643 
1644 	isid = -1;
1645 	status = pt_image_read(&ifix->copy, &isid, buffer, 1, &ifix->asid[0],
1646 			       0x2009ull);
1647 	ptu_int_eq(status, 1);
1648 	ptu_int_eq(isid, 3);
1649 	ptu_uint_eq(buffer[0], 0x01);
1650 	ptu_uint_eq(buffer[1], 0xcc);
1651 
1652 	isid = -1;
1653 	status = pt_image_read(&ifix->copy, &isid, buffer, 1, &ifix->asid[0],
1654 			       0x2000ull);
1655 	ptu_int_eq(status, 1);
1656 	ptu_int_eq(isid, 1);
1657 	ptu_uint_eq(buffer[0], 0x00);
1658 	ptu_uint_eq(buffer[1], 0xcc);
1659 
1660 	return ptu_passed();
1661 }
1662 
1663 static struct ptunit_result copy_merge(struct image_fixture *ifix)
1664 {
1665 	uint8_t buffer[] = { 0xcc, 0xcc };
1666 	int status, isid;
1667 
1668 	ifix->section[1].size = 0x8;
1669 	ifix->mapping[1].size = 0x8;
1670 
1671 	status = pt_image_add(&ifix->copy, &ifix->section[1], &ifix->asid[0],
1672 			      0x2000ull, 1);
1673 	ptu_int_eq(status, 0);
1674 
1675 	ifix->section[2].size = 0x8;
1676 	ifix->mapping[2].size = 0x8;
1677 
1678 	status = pt_image_add(&ifix->copy, &ifix->section[2], &ifix->asid[0],
1679 			      0x2008ull, 2);
1680 	ptu_int_eq(status, 0);
1681 
1682 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
1683 			      0x2000ull, 3);
1684 	ptu_int_eq(status, 0);
1685 
1686 	status = pt_image_copy(&ifix->copy, &ifix->image);
1687 	ptu_int_eq(status, 0);
1688 
1689 	isid = -1;
1690 	status = pt_image_read(&ifix->copy, &isid, buffer, 1, &ifix->asid[0],
1691 			       0x2003ull);
1692 	ptu_int_eq(status, 1);
1693 	ptu_int_eq(isid, 3);
1694 	ptu_uint_eq(buffer[0], 0x03);
1695 	ptu_uint_eq(buffer[1], 0xcc);
1696 
1697 	isid = -1;
1698 	status = pt_image_read(&ifix->copy, &isid, buffer, 1, &ifix->asid[0],
1699 			       0x200aull);
1700 	ptu_int_eq(status, 1);
1701 	ptu_int_eq(isid, 3);
1702 	ptu_uint_eq(buffer[0], 0x0a);
1703 	ptu_uint_eq(buffer[1], 0xcc);
1704 
1705 	return ptu_passed();
1706 }
1707 
1708 static struct ptunit_result copy_overlap(struct image_fixture *ifix)
1709 {
1710 	uint8_t buffer[] = { 0xcc, 0xcc };
1711 	int status, isid;
1712 
1713 	status = pt_image_add(&ifix->copy, &ifix->section[0], &ifix->asid[0],
1714 			      0x2000ull, 1);
1715 	ptu_int_eq(status, 0);
1716 
1717 	status = pt_image_add(&ifix->copy, &ifix->section[1], &ifix->asid[0],
1718 			      0x2010ull, 2);
1719 	ptu_int_eq(status, 0);
1720 
1721 	status = pt_image_add(&ifix->image, &ifix->section[2], &ifix->asid[0],
1722 			      0x2008ull, 3);
1723 	ptu_int_eq(status, 0);
1724 
1725 	status = pt_image_copy(&ifix->copy, &ifix->image);
1726 	ptu_int_eq(status, 0);
1727 
1728 	isid = -1;
1729 	status = pt_image_read(&ifix->copy, &isid, buffer, 1, &ifix->asid[0],
1730 			       0x2003ull);
1731 	ptu_int_eq(status, 1);
1732 	ptu_int_eq(isid, 1);
1733 	ptu_uint_eq(buffer[0], 0x03);
1734 	ptu_uint_eq(buffer[1], 0xcc);
1735 
1736 	isid = -1;
1737 	status = pt_image_read(&ifix->copy, &isid, buffer, 1, &ifix->asid[0],
1738 			       0x200aull);
1739 	ptu_int_eq(status, 1);
1740 	ptu_int_eq(isid, 3);
1741 	ptu_uint_eq(buffer[0], 0x02);
1742 	ptu_uint_eq(buffer[1], 0xcc);
1743 
1744 	isid = -1;
1745 	status = pt_image_read(&ifix->copy, &isid, buffer, 1, &ifix->asid[0],
1746 			       0x2016ull);
1747 	ptu_int_eq(status, 1);
1748 	ptu_int_eq(isid, 3);
1749 	ptu_uint_eq(buffer[0], 0x0e);
1750 	ptu_uint_eq(buffer[1], 0xcc);
1751 
1752 	isid = -1;
1753 	status = pt_image_read(&ifix->copy, &isid, buffer, 1, &ifix->asid[0],
1754 			       0x2019ull);
1755 	ptu_int_eq(status, 1);
1756 	ptu_int_eq(isid, 2);
1757 	ptu_uint_eq(buffer[0], 0x09);
1758 	ptu_uint_eq(buffer[1], 0xcc);
1759 
1760 	return ptu_passed();
1761 }
1762 
1763 static struct ptunit_result copy_replace(struct image_fixture *ifix)
1764 {
1765 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1766 	int status, isid;
1767 
1768 	ifix->section[0].size = 0x8;
1769 	ifix->mapping[0].size = 0x8;
1770 
1771 	status = pt_image_add(&ifix->copy, &ifix->section[0], &ifix->asid[0],
1772 			      0x1004ull, 1);
1773 	ptu_int_eq(status, 0);
1774 
1775 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[0],
1776 			      0x1000ull, 2);
1777 	ptu_int_eq(status, 0);
1778 
1779 	status = pt_image_copy(&ifix->copy, &ifix->image);
1780 	ptu_int_eq(status, 0);
1781 
1782 	isid = -1;
1783 	status = pt_image_read(&ifix->copy, &isid, buffer, 2, &ifix->asid[0],
1784 			       0x1003ull);
1785 	ptu_int_eq(status, 2);
1786 	ptu_int_eq(isid, 2);
1787 	ptu_uint_eq(buffer[0], 0x03);
1788 	ptu_uint_eq(buffer[1], 0x04);
1789 	ptu_uint_eq(buffer[2], 0xcc);
1790 
1791 	return ptu_passed();
1792 }
1793 
1794 static struct ptunit_result add_cached_null(void)
1795 {
1796 	struct pt_image_section_cache iscache;
1797 	struct pt_image image;
1798 	int status;
1799 
1800 	status = pt_image_add_cached(NULL, &iscache, 0, NULL);
1801 	ptu_int_eq(status, -pte_invalid);
1802 
1803 	status = pt_image_add_cached(&image, NULL, 0, NULL);
1804 	ptu_int_eq(status, -pte_invalid);
1805 
1806 	return ptu_passed();
1807 }
1808 
1809 static struct ptunit_result add_cached(struct image_fixture *ifix)
1810 {
1811 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1812 	int status, isid, risid;
1813 
1814 	isid = ifix_cache_section(ifix, &ifix->section[0], 0x1000ull);
1815 	ptu_int_gt(isid, 0);
1816 
1817 	status = pt_image_add_cached(&ifix->image, &ifix->iscache, isid,
1818 				      &ifix->asid[0]);
1819 	ptu_int_eq(status, 0);
1820 
1821 	risid = -1;
1822 	status = pt_image_read(&ifix->image, &risid, buffer, 2, &ifix->asid[0],
1823 			       0x1003ull);
1824 	ptu_int_eq(status, 2);
1825 	ptu_int_eq(risid, isid);
1826 	ptu_uint_eq(buffer[0], 0x03);
1827 	ptu_uint_eq(buffer[1], 0x04);
1828 	ptu_uint_eq(buffer[2], 0xcc);
1829 
1830 	return ptu_passed();
1831 }
1832 
1833 static struct ptunit_result add_cached_null_asid(struct image_fixture *ifix)
1834 {
1835 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1836 	int status, isid, risid;
1837 
1838 	isid = ifix_cache_section(ifix, &ifix->section[0], 0x1000ull);
1839 	ptu_int_gt(isid, 0);
1840 
1841 	status = pt_image_add_cached(&ifix->image, &ifix->iscache, isid, NULL);
1842 	ptu_int_eq(status, 0);
1843 
1844 	risid = -1;
1845 	status = pt_image_read(&ifix->image, &risid, buffer, 2, &ifix->asid[0],
1846 			       0x1003ull);
1847 	ptu_int_eq(status, 2);
1848 	ptu_int_eq(risid, isid);
1849 	ptu_uint_eq(buffer[0], 0x03);
1850 	ptu_uint_eq(buffer[1], 0x04);
1851 	ptu_uint_eq(buffer[2], 0xcc);
1852 
1853 	return ptu_passed();
1854 }
1855 
1856 static struct ptunit_result add_cached_twice(struct image_fixture *ifix)
1857 {
1858 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1859 	int status, isid, risid;
1860 
1861 	isid = ifix_cache_section(ifix, &ifix->section[0], 0x1000ull);
1862 	ptu_int_gt(isid, 0);
1863 
1864 	status = pt_image_add_cached(&ifix->image, &ifix->iscache, isid,
1865 				      &ifix->asid[0]);
1866 	ptu_int_eq(status, 0);
1867 
1868 	status = pt_image_add_cached(&ifix->image, &ifix->iscache, isid,
1869 				      &ifix->asid[0]);
1870 	ptu_int_eq(status, 0);
1871 
1872 	risid = -1;
1873 	status = pt_image_read(&ifix->image, &risid, buffer, 2, &ifix->asid[0],
1874 			       0x1003ull);
1875 	ptu_int_eq(status, 2);
1876 	ptu_int_eq(risid, isid);
1877 	ptu_uint_eq(buffer[0], 0x03);
1878 	ptu_uint_eq(buffer[1], 0x04);
1879 	ptu_uint_eq(buffer[2], 0xcc);
1880 
1881 	return ptu_passed();
1882 }
1883 
1884 static struct ptunit_result add_cached_bad_isid(struct image_fixture *ifix)
1885 {
1886 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1887 	int status, isid;
1888 
1889 	status = pt_image_add_cached(&ifix->image, &ifix->iscache, 1,
1890 				      &ifix->asid[0]);
1891 	ptu_int_eq(status, -pte_bad_image);
1892 
1893 	isid = -1;
1894 	status = pt_image_read(&ifix->image, &isid, buffer, 2, &ifix->asid[0],
1895 			       0x1003ull);
1896 	ptu_int_eq(status, -pte_nomap);
1897 	ptu_int_eq(isid, -1);
1898 
1899 	return ptu_passed();
1900 }
1901 
1902 static struct ptunit_result find_null(struct image_fixture *ifix)
1903 {
1904 	struct pt_mapped_section msec;
1905 	int status;
1906 
1907 	status = pt_image_find(NULL, &msec, &ifix->asid[0],
1908 			       0x1000ull);
1909 	ptu_int_eq(status, -pte_internal);
1910 
1911 	status = pt_image_find(&ifix->image, NULL, &ifix->asid[0],
1912 			       0x1000ull);
1913 	ptu_int_eq(status, -pte_internal);
1914 
1915 	status = pt_image_find(&ifix->image, &msec, NULL, 0x1000ull);
1916 	ptu_int_eq(status, -pte_internal);
1917 
1918 	return ptu_passed();
1919 }
1920 
1921 static struct ptunit_result find(struct image_fixture *ifix)
1922 {
1923 	struct pt_mapped_section msec;
1924 	int status;
1925 
1926 	status = pt_image_find(&ifix->image, &msec, &ifix->asid[1], 0x2003ull);
1927 	ptu_int_eq(status, 11);
1928 	ptu_ptr_eq(msec.section, &ifix->section[1]);
1929 	ptu_uint_eq(msec.vaddr, 0x2000ull);
1930 
1931 	status = pt_section_put(msec.section);
1932 	ptu_int_eq(status, 0);
1933 
1934 	return ptu_passed();
1935 }
1936 
1937 static struct ptunit_result find_asid(struct image_fixture *ifix)
1938 {
1939 	struct pt_mapped_section msec;
1940 	int status;
1941 
1942 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
1943 			      0x1000ull, 1);
1944 	ptu_int_eq(status, 0);
1945 
1946 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[1],
1947 			      0x1008ull, 2);
1948 	ptu_int_eq(status, 0);
1949 
1950 	status = pt_image_find(&ifix->image, &msec, &ifix->asid[0], 0x1009ull);
1951 	ptu_int_eq(status, 1);
1952 	ptu_ptr_eq(msec.section, &ifix->section[0]);
1953 	ptu_uint_eq(msec.vaddr, 0x1000ull);
1954 
1955 	status = pt_section_put(msec.section);
1956 	ptu_int_eq(status, 0);
1957 
1958 	status = pt_image_find(&ifix->image, &msec, &ifix->asid[1], 0x1009ull);
1959 	ptu_int_eq(status, 2);
1960 	ptu_ptr_eq(msec.section, &ifix->section[0]);
1961 	ptu_uint_eq(msec.vaddr, 0x1008ull);
1962 
1963 	status = pt_section_put(msec.section);
1964 	ptu_int_eq(status, 0);
1965 
1966 	return ptu_passed();
1967 }
1968 
1969 static struct ptunit_result find_bad_asid(struct image_fixture *ifix)
1970 {
1971 	struct pt_mapped_section msec;
1972 	int status;
1973 
1974 	status = pt_image_find(&ifix->image, &msec, &ifix->asid[0], 0x2003ull);
1975 	ptu_int_eq(status, -pte_nomap);
1976 
1977 	return ptu_passed();
1978 }
1979 
1980 static struct ptunit_result find_nomem(struct image_fixture *ifix)
1981 {
1982 	struct pt_mapped_section msec;
1983 	int status;
1984 
1985 	status = pt_image_find(&ifix->image, &msec, &ifix->asid[1], 0x1010ull);
1986 	ptu_int_eq(status, -pte_nomap);
1987 
1988 	return ptu_passed();
1989 }
1990 
1991 static struct ptunit_result validate_null(struct image_fixture *ifix)
1992 {
1993 	struct pt_mapped_section msec;
1994 	int status;
1995 
1996 	status = pt_image_validate(NULL, &msec, 0x1004ull, 10);
1997 	ptu_int_eq(status, -pte_internal);
1998 
1999 	status = pt_image_validate(&ifix->image, NULL, 0x1004ull, 10);
2000 	ptu_int_eq(status, -pte_internal);
2001 
2002 	return ptu_passed();
2003 }
2004 
2005 static struct ptunit_result validate(struct image_fixture *ifix)
2006 {
2007 	struct pt_mapped_section msec;
2008 	int isid, status;
2009 
2010 	isid = pt_image_find(&ifix->image, &msec, &ifix->asid[0], 0x1003ull);
2011 	ptu_int_ge(isid, 0);
2012 
2013 	status = pt_section_put(msec.section);
2014 	ptu_int_eq(status, 0);
2015 
2016 	status = pt_image_validate(&ifix->image, &msec, 0x1004ull, isid);
2017 	ptu_int_eq(status, 0);
2018 
2019 	return ptu_passed();
2020 }
2021 
2022 static struct ptunit_result validate_bad_asid(struct image_fixture *ifix)
2023 {
2024 	struct pt_mapped_section msec;
2025 	int isid, status;
2026 
2027 	isid = pt_image_find(&ifix->image, &msec, &ifix->asid[0], 0x1003ull);
2028 	ptu_int_ge(isid, 0);
2029 
2030 	status = pt_section_put(msec.section);
2031 	ptu_int_eq(status, 0);
2032 
2033 	msec.asid = ifix->asid[1];
2034 
2035 	status = pt_image_validate(&ifix->image, &msec, 0x1004ull, isid);
2036 	ptu_int_eq(status, -pte_nomap);
2037 
2038 	return ptu_passed();
2039 }
2040 
2041 static struct ptunit_result validate_bad_vaddr(struct image_fixture *ifix)
2042 {
2043 	struct pt_mapped_section msec;
2044 	int isid, status;
2045 
2046 	isid = pt_image_find(&ifix->image, &msec, &ifix->asid[0], 0x1003ull);
2047 	ptu_int_ge(isid, 0);
2048 
2049 	status = pt_section_put(msec.section);
2050 	ptu_int_eq(status, 0);
2051 
2052 	msec.vaddr = 0x2000ull;
2053 
2054 	status = pt_image_validate(&ifix->image, &msec, 0x1004ull, isid);
2055 	ptu_int_eq(status, -pte_nomap);
2056 
2057 	return ptu_passed();
2058 }
2059 
2060 static struct ptunit_result validate_bad_offset(struct image_fixture *ifix)
2061 {
2062 	struct pt_mapped_section msec;
2063 	int isid, status;
2064 
2065 	isid = pt_image_find(&ifix->image, &msec, &ifix->asid[0], 0x1003ull);
2066 	ptu_int_ge(isid, 0);
2067 
2068 	status = pt_section_put(msec.section);
2069 	ptu_int_eq(status, 0);
2070 
2071 	msec.offset = 0x8ull;
2072 
2073 	status = pt_image_validate(&ifix->image, &msec, 0x1004ull, isid);
2074 	ptu_int_eq(status, -pte_nomap);
2075 
2076 	return ptu_passed();
2077 }
2078 
2079 static struct ptunit_result validate_bad_size(struct image_fixture *ifix)
2080 {
2081 	struct pt_mapped_section msec;
2082 	int isid, status;
2083 
2084 	isid = pt_image_find(&ifix->image, &msec, &ifix->asid[0], 0x1003ull);
2085 	ptu_int_ge(isid, 0);
2086 
2087 	status = pt_section_put(msec.section);
2088 	ptu_int_eq(status, 0);
2089 
2090 	msec.size = 0x8ull;
2091 
2092 	status = pt_image_validate(&ifix->image, &msec, 0x1004ull, isid);
2093 	ptu_int_eq(status, -pte_nomap);
2094 
2095 	return ptu_passed();
2096 }
2097 
2098 static struct ptunit_result validate_bad_isid(struct image_fixture *ifix)
2099 {
2100 	struct pt_mapped_section msec;
2101 	int isid, status;
2102 
2103 	isid = pt_image_find(&ifix->image, &msec, &ifix->asid[0], 0x1003ull);
2104 	ptu_int_ge(isid, 0);
2105 
2106 	status = pt_section_put(msec.section);
2107 	ptu_int_eq(status, 0);
2108 
2109 	status = pt_image_validate(&ifix->image, &msec, 0x1004ull, isid + 1);
2110 	ptu_int_eq(status, -pte_nomap);
2111 
2112 	return ptu_passed();
2113 }
2114 
2115 static struct ptunit_result ifix_init(struct image_fixture *ifix)
2116 {
2117 	int index;
2118 
2119 	pt_image_init(&ifix->image, NULL);
2120 	pt_image_init(&ifix->copy, NULL);
2121 
2122 	memset(ifix->status, 0, sizeof(ifix->status));
2123 	memset(ifix->mapping, 0, sizeof(ifix->mapping));
2124 	memset(ifix->section, 0, sizeof(ifix->section));
2125 	memset(&ifix->iscache, 0, sizeof(ifix->iscache));
2126 
2127 	ifix->nsecs = 0;
2128 
2129 	index = ifix_add_section(ifix, "file-0");
2130 	ptu_int_eq(index, 0);
2131 
2132 	index = ifix_add_section(ifix, "file-1");
2133 	ptu_int_eq(index, 1);
2134 
2135 	index = ifix_add_section(ifix, "file-2");
2136 	ptu_int_eq(index, 2);
2137 
2138 	pt_asid_init(&ifix->asid[0]);
2139 	ifix->asid[0].cr3 = 0xa000;
2140 
2141 	pt_asid_init(&ifix->asid[1]);
2142 	ifix->asid[1].cr3 = 0xb000;
2143 
2144 	pt_asid_init(&ifix->asid[2]);
2145 	ifix->asid[2].cr3 = 0xc000;
2146 
2147 	return ptu_passed();
2148 }
2149 
2150 static struct ptunit_result rfix_init(struct image_fixture *ifix)
2151 {
2152 	int status;
2153 
2154 	ptu_check(ifix_init, ifix);
2155 
2156 	status = pt_image_add(&ifix->image, &ifix->section[0], &ifix->asid[0],
2157 			      0x1000ull, 10);
2158 	ptu_int_eq(status, 0);
2159 
2160 	status = pt_image_add(&ifix->image, &ifix->section[1], &ifix->asid[1],
2161 			      0x2000ull, 11);
2162 	ptu_int_eq(status, 0);
2163 
2164 	return ptu_passed();
2165 }
2166 
2167 static struct ptunit_result dfix_fini(struct image_fixture *ifix)
2168 {
2169 	pt_image_fini(&ifix->image);
2170 
2171 	return ptu_passed();
2172 }
2173 
2174 static struct ptunit_result ifix_fini(struct image_fixture *ifix)
2175 {
2176 	int sec;
2177 
2178 	ptu_check(dfix_fini, ifix);
2179 
2180 	pt_image_fini(&ifix->copy);
2181 
2182 	for (sec = 0; sec < ifix_nsecs; ++sec) {
2183 		ptu_int_eq(ifix->section[sec].ucount, 0);
2184 		ptu_int_eq(ifix->section[sec].mcount, 0);
2185 		ptu_int_le(ifix->status[sec].deleted, 1);
2186 		ptu_int_eq(ifix->status[sec].bad_put, 0);
2187 	}
2188 
2189 	return ptu_passed();
2190 }
2191 
2192 int main(int argc, char **argv)
2193 {
2194 	struct image_fixture dfix, ifix, rfix;
2195 	struct ptunit_suite suite;
2196 
2197 	/* Dfix provides image destruction. */
2198 	dfix.init = NULL;
2199 	dfix.fini = dfix_fini;
2200 
2201 	/* Ifix provides an empty image. */
2202 	ifix.init = ifix_init;
2203 	ifix.fini = ifix_fini;
2204 
2205 	/* Rfix provides an image with two sections added. */
2206 	rfix.init = rfix_init;
2207 	rfix.fini = ifix_fini;
2208 
2209 	suite = ptunit_mk_suite(argc, argv);
2210 
2211 	ptu_run(suite, init);
2212 	ptu_run_f(suite, init_name, dfix);
2213 	ptu_run(suite, init_null);
2214 
2215 	ptu_run(suite, fini);
2216 	ptu_run(suite, fini_empty);
2217 	ptu_run(suite, fini_null);
2218 
2219 	ptu_run_f(suite, name, dfix);
2220 	ptu_run(suite, name_none);
2221 	ptu_run(suite, name_null);
2222 
2223 	ptu_run_f(suite, read_empty, ifix);
2224 	ptu_run_f(suite, overlap_front, ifix);
2225 	ptu_run_f(suite, overlap_back, ifix);
2226 	ptu_run_f(suite, overlap_multiple, ifix);
2227 	ptu_run_f(suite, overlap_mid, ifix);
2228 	ptu_run_f(suite, contained, ifix);
2229 	ptu_run_f(suite, contained_multiple, ifix);
2230 	ptu_run_f(suite, contained_back, ifix);
2231 	ptu_run_f(suite, same, ifix);
2232 	ptu_run_f(suite, same_different_isid, ifix);
2233 	ptu_run_f(suite, same_different_offset, ifix);
2234 	ptu_run_f(suite, adjacent, ifix);
2235 
2236 	ptu_run_f(suite, read_null, rfix);
2237 	ptu_run_f(suite, read, rfix);
2238 	ptu_run_f(suite, read_null, rfix);
2239 	ptu_run_f(suite, read_asid, ifix);
2240 	ptu_run_f(suite, read_bad_asid, rfix);
2241 	ptu_run_f(suite, read_null_asid, rfix);
2242 	ptu_run_f(suite, read_callback, rfix);
2243 	ptu_run_f(suite, read_nomem, rfix);
2244 	ptu_run_f(suite, read_truncated, rfix);
2245 	ptu_run_f(suite, read_error, rfix);
2246 	ptu_run_f(suite, read_spurious_error, rfix);
2247 
2248 	ptu_run_f(suite, remove_section, rfix);
2249 	ptu_run_f(suite, remove_bad_vaddr, rfix);
2250 	ptu_run_f(suite, remove_bad_asid, rfix);
2251 	ptu_run_f(suite, remove_by_filename, rfix);
2252 	ptu_run_f(suite, remove_by_filename_bad_asid, rfix);
2253 	ptu_run_f(suite, remove_none_by_filename, rfix);
2254 	ptu_run_f(suite, remove_all_by_filename, ifix);
2255 	ptu_run_f(suite, remove_by_asid, rfix);
2256 
2257 	ptu_run_f(suite, copy_empty, ifix);
2258 	ptu_run_f(suite, copy, rfix);
2259 	ptu_run_f(suite, copy_self, rfix);
2260 	ptu_run_f(suite, copy_shrink, rfix);
2261 	ptu_run_f(suite, copy_split, ifix);
2262 	ptu_run_f(suite, copy_merge, ifix);
2263 	ptu_run_f(suite, copy_overlap, ifix);
2264 	ptu_run_f(suite, copy_replace, ifix);
2265 
2266 	ptu_run(suite, add_cached_null);
2267 	ptu_run_f(suite, add_cached, ifix);
2268 	ptu_run_f(suite, add_cached_null_asid, ifix);
2269 	ptu_run_f(suite, add_cached_twice, ifix);
2270 	ptu_run_f(suite, add_cached_bad_isid, ifix);
2271 
2272 	ptu_run_f(suite, find_null, rfix);
2273 	ptu_run_f(suite, find, rfix);
2274 	ptu_run_f(suite, find_asid, ifix);
2275 	ptu_run_f(suite, find_bad_asid, rfix);
2276 	ptu_run_f(suite, find_nomem, rfix);
2277 
2278 	ptu_run_f(suite, validate_null, rfix);
2279 	ptu_run_f(suite, validate, rfix);
2280 	ptu_run_f(suite, validate_bad_asid, rfix);
2281 	ptu_run_f(suite, validate_bad_vaddr, rfix);
2282 	ptu_run_f(suite, validate_bad_offset, rfix);
2283 	ptu_run_f(suite, validate_bad_size, rfix);
2284 	ptu_run_f(suite, validate_bad_isid, rfix);
2285 
2286 	return ptunit_report(&suite);
2287 }
2288