static struct ptunit_result from_user_null(void) { struct pt_asid user; int errcode; pt_asid_init(&user); errcode = pt_asid_from_user(NULL, NULL); ptu_int_eq(errcode, -pte_internal); errcode = pt_asid_from_user(NULL, &user); ptu_int_eq(errcode, -pte_internal); return ptu_passed(); }
int pt_image_add_cached(struct pt_image *image, struct pt_image_section_cache *iscache, int isid, const struct pt_asid *uasid) { struct pt_section *section; struct pt_asid asid; uint64_t vaddr; int errcode, status; if (!image || !iscache) return -pte_invalid; errcode = pt_iscache_lookup(iscache, §ion, &vaddr, isid); if (errcode < 0) return errcode; errcode = pt_asid_from_user(&asid, uasid); if (errcode < 0) return errcode; status = pt_image_add(image, section, &asid, vaddr, isid); /* We grab a reference when we add the section. Drop the one we * obtained from cache lookup. */ errcode = pt_section_put(section); if (errcode < 0) return errcode; return status; }
int pt_image_add_file(struct pt_image *image, const char *filename, uint64_t offset, uint64_t size, const struct pt_asid *uasid, uint64_t vaddr) { struct pt_section *section; struct pt_asid asid; int errcode; if (!image || !filename) return -pte_invalid; errcode = pt_asid_from_user(&asid, uasid); if (errcode < 0) return errcode; section = pt_mk_section(filename, offset, size); if (!section) return -pte_invalid; errcode = pt_image_add(image, section, &asid, vaddr, 0); if (errcode < 0) { (void) pt_section_put(section); return errcode; } /* The image list got its own reference; let's drop ours. */ errcode = pt_section_put(section); if (errcode < 0) return errcode; return 0; }
static struct ptunit_result from_user_default(void) { struct pt_asid asid; int errcode; errcode = pt_asid_from_user(&asid, NULL); ptu_int_eq(errcode, 0); ptu_uint_eq(asid.size, sizeof(asid)); ptu_uint_eq(asid.cr3, pt_asid_no_cr3); ptu_uint_eq(asid.vmcs, pt_asid_no_vmcs); return ptu_passed(); }
int pt_image_remove_by_filename(struct pt_image *image, const char *filename, const struct pt_asid *uasid) { struct pt_section_list **list; struct pt_asid asid; int errcode, removed; if (!image || !filename) return -pte_invalid; errcode = pt_asid_from_user(&asid, uasid); if (errcode < 0) return errcode; removed = 0; for (list = &image->sections; *list;) { struct pt_mapped_section *msec; const struct pt_section *sec; const struct pt_asid *masid; struct pt_section_list *trash; const char *tname; trash = *list; msec = &trash->section; masid = pt_msec_asid(msec); errcode = pt_asid_match(masid, &asid); if (errcode < 0) return errcode; if (!errcode) { list = &trash->next; continue; } sec = pt_msec_section(msec); tname = pt_section_filename(sec); if (tname && (strcmp(tname, filename) == 0)) { *list = trash->next; pt_section_list_free(trash); removed += 1; } else list = &trash->next; } return removed; }
static struct ptunit_result from_user_small(void) { struct pt_asid asid, user; int errcode; user.size = sizeof(user.size); errcode = pt_asid_from_user(&asid, &user); ptu_int_eq(errcode, 0); ptu_uint_eq(asid.size, sizeof(asid)); ptu_uint_eq(asid.cr3, pt_asid_no_cr3); ptu_uint_eq(asid.vmcs, pt_asid_no_vmcs); return ptu_passed(); }
static struct ptunit_result from_user_big(void) { struct pt_asid asid, user; int errcode; user.size = sizeof(user) + 4; user.cr3 = 0x4200ull; user.vmcs = 0x23000ull; errcode = pt_asid_from_user(&asid, &user); ptu_int_eq(errcode, 0); ptu_uint_eq(asid.size, sizeof(asid)); ptu_uint_eq(asid.cr3, 0x4200ull); ptu_uint_eq(asid.vmcs, 0x23000ull); return ptu_passed(); }
int pt_image_remove_by_asid(struct pt_image *image, const struct pt_asid *uasid) { struct pt_section_list **list; struct pt_asid asid; int errcode, removed; if (!image) return -pte_invalid; errcode = pt_asid_from_user(&asid, uasid); if (errcode < 0) return errcode; removed = 0; for (list = &image->sections; *list;) { struct pt_mapped_section *msec; const struct pt_asid *masid; struct pt_section_list *trash; trash = *list; msec = &trash->section; masid = pt_msec_asid(msec); errcode = pt_asid_match(masid, &asid); if (errcode < 0) return errcode; if (!errcode) { list = &trash->next; continue; } *list = trash->next; pt_section_list_free(trash); removed += 1; } return removed; }