Exemple #1
0
static struct pt_section_list *pt_mk_section_list(struct pt_section *section,
						  const struct pt_asid *asid,
						  uint64_t vaddr, int isid)
{
	struct pt_section_list *list;
	int errcode;

	list = malloc(sizeof(*list));
	if (!list)
		return NULL;

	memset(list, 0, sizeof(*list));

	errcode = pt_section_get(section);
	if (errcode < 0)
		goto out_mem;

	pt_msec_init(&list->section, section, asid, vaddr);
	list->isid = isid;

	return list;

out_mem:
	free(list);
	return NULL;
}
static struct ptunit_result get_null(void)
{
	int errcode;

	errcode = pt_section_get(NULL);
	ptu_int_eq(errcode, -pte_internal);

	return ptu_passed();
}
static struct ptunit_result get_put(struct section_fixture *sfix)
{
	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
	int errcode;

	sfix_write(sfix, bytes);

	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
	ptu_ptr(sfix->section);

	errcode = pt_section_get(sfix->section);
	ptu_int_eq(errcode, 0);

	errcode = pt_section_get(sfix->section);
	ptu_int_eq(errcode, 0);

	errcode = pt_section_put(sfix->section);
	ptu_int_eq(errcode, 0);

	errcode = pt_section_put(sfix->section);
	ptu_int_eq(errcode, 0);

	return ptu_passed();
}
static int worker(void *arg)
{
	struct section_fixture *sfix;
	int it, errcode;

	sfix = arg;
	if (!sfix)
		return -pte_internal;

	for (it = 0; it < num_work; ++it) {
		uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
		int read;

		errcode = pt_section_get(sfix->section);
		if (errcode < 0)
			return errcode;

		errcode = pt_section_map(sfix->section);
		if (errcode < 0)
			goto out_put;

		read = pt_section_read(sfix->section, buffer, 2, 0x0ull);
		if (read < 0)
			goto out_unmap;

		errcode = -pte_invalid;
		if ((read != 2) || (buffer[0] != 0x2) || (buffer[1] != 0x4))
			goto out_unmap;

		errcode = pt_section_unmap(sfix->section);
		if (errcode < 0)
			goto out_put;

		errcode = pt_section_put(sfix->section);
		if (errcode < 0)
			return errcode;
	}

	return 0;

out_unmap:
	(void) pt_section_unmap(sfix->section);

out_put:
	(void) pt_section_put(sfix->section);
	return errcode;
}
static struct ptunit_result get_overflow(struct section_fixture *sfix)
{
	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
	int errcode;

	sfix_write(sfix, bytes);

	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
	ptu_ptr(sfix->section);

	sfix->section->ucount = UINT16_MAX;

	errcode = pt_section_get(sfix->section);
	ptu_int_eq(errcode, -pte_internal);

	sfix->section->ucount = 1;

	return ptu_passed();
}
Exemple #6
0
int pt_iscache_lookup(struct pt_image_section_cache *iscache,
		      struct pt_section **section, uint64_t *laddr, int isid)
{
	uint16_t index;
	int errcode, status;

	if (!iscache || !section || !laddr)
		return -pte_internal;

	if (isid <= 0)
		return -pte_bad_image;

	isid -= 1;
	if (isid > UINT16_MAX)
		return -pte_internal;

	index = (uint16_t) isid;

	errcode = pt_iscache_lock(iscache);
	if (errcode < 0)
		return errcode;

	if (iscache->size <= index)
		status = -pte_bad_image;
	else {
		const struct pt_iscache_entry *entry;

		entry = &iscache->entries[index];
		*section = entry->section;
		*laddr = entry->laddr;

		status = pt_section_get(*section);
	}

	errcode = pt_iscache_unlock(iscache);
	if (errcode < 0)
		return errcode;

	return status;
}
Exemple #7
0
int pt_image_find(struct pt_image *image, struct pt_section **psection,
		  uint64_t *laddr, const struct pt_asid *asid, uint64_t vaddr)
{
	struct pt_mapped_section *msec;
	struct pt_section_list *slist;
	struct pt_section *section;
	int errcode;

	if (!image || !psection || !laddr)
		return -pte_internal;

	slist = image->sections;
	if (!slist)
		return -pte_nomap;

	if (!slist->mapped)
		return pt_image_find_cold(image, psection, laddr, asid, vaddr);

	msec = &slist->section;

	errcode = pt_image_check_msec(msec, asid, vaddr);
	if (errcode < 0) {
		if (errcode != -pte_nomap)
			return errcode;

		return pt_image_find_cold(image, psection, laddr, asid, vaddr);
	}

	section = pt_msec_section(msec);

	errcode = pt_section_get(section);
	if (errcode < 0)
		return errcode;

	*psection = section;
	*laddr = pt_msec_begin(msec);

	return slist->isid;
}
Exemple #8
0
int pt_iscache_add(struct pt_image_section_cache *iscache,
		   struct pt_section *section, uint64_t laddr)
{
	uint16_t idx, end;
	int errcode;

	if (!iscache || !section)
		return -pte_internal;

	/* We must have a filename for @section. */
	if (!pt_section_filename(section))
		return -pte_internal;

	errcode = pt_iscache_lock(iscache);
	if (errcode < 0)
		return errcode;

	end = iscache->size;
	for (idx = 0; idx < end; ++idx) {
		const struct pt_iscache_entry *entry;
		struct pt_section *sec;

		entry = &iscache->entries[idx];

		/* We do not zero-initialize the array - a NULL check is
		 * pointless.
		 */
		sec = entry->section;

		errcode = section_match(section, sec);
		if (errcode <= 0) {
			if (errcode < 0)
				goto out_unlock;

			continue;
		}

		/* Use the cached section instead of the argument section.
		 *
		 * We'll be able to drop the argument section in this case and
		 * only keep one copy around and, more importantly, mapped.
		 */
		section = sec;

		/* If we also find a matching load address, we're done. */
		if (laddr == entry->laddr)
			break;
	}

	/* If we have not found a matching entry, add one. */
	if (idx == end) {
		struct pt_iscache_entry *entry;

		/* Expand the cache, if necessary. */
		if (iscache->capacity <= iscache->size) {
			/* We must never exceed the capacity. */
			if (iscache->capacity < iscache->size) {
				errcode = -pte_internal;
				goto out_unlock;
			}

			errcode = pt_iscache_expand(iscache);
			if (errcode < 0)
				goto out_unlock;

			/* Make sure it is big enough, now. */
			if (iscache->capacity <= iscache->size) {
				errcode = -pte_internal;
				goto out_unlock;
			}
		}

		errcode = pt_section_get(section);
		if (errcode < 0)
			goto out_unlock;

		idx = iscache->size++;

		entry = &iscache->entries[idx];
		entry->section = section;
		entry->laddr = laddr;
	}

	errcode = pt_iscache_unlock(iscache);
	if (errcode < 0)
		return errcode;

	return isid_from_index(idx);

 out_unlock:
	(void) pt_iscache_unlock(iscache);
	return errcode;
}