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