]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/processor-trace/libipt/test/src/ptunit-image.c
Upgrade to OpenSSH 7.8p1.
[FreeBSD/FreeBSD.git] / contrib / processor-trace / libipt / test / src / ptunit-image.c
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 }