Ejemplo n.º 1
0
static struct ptunit_result next_null(void)
{
	struct pt_encoder encoder;
	struct pt_packet packet;
	int errcode;

	errcode = pt_enc_next(NULL, &packet);
	ptu_int_eq(errcode, -pte_invalid);

	errcode = pt_enc_next(&encoder, NULL);
	ptu_int_eq(errcode, -pte_invalid);

	return ptu_passed();
}
Ejemplo n.º 2
0
int pt_encode_psbend(struct pt_encoder *encoder)
{
	struct pt_packet packet;

	packet.type = ppt_psbend;

	return pt_enc_next(encoder, &packet);
}
Ejemplo n.º 3
0
int pt_encode_ovf(struct pt_encoder *encoder)
{
	struct pt_packet packet;

	packet.type = ppt_ovf;

	return pt_enc_next(encoder, &packet);
}
Ejemplo n.º 4
0
int pt_encode_cbr(struct pt_encoder *encoder, uint8_t cbr)
{
	struct pt_packet packet;

	packet.type = ppt_cbr;
	packet.payload.cbr.ratio = cbr;

	return pt_enc_next(encoder, &packet);
}
Ejemplo n.º 5
0
int pt_encode_tsc(struct pt_encoder *encoder, uint64_t tsc)
{
	struct pt_packet packet;

	packet.type = ppt_tsc;
	packet.payload.tsc.tsc = tsc;

	return pt_enc_next(encoder, &packet);
}
Ejemplo n.º 6
0
int pt_encode_pip(struct pt_encoder *encoder, uint64_t cr3)
{
	struct pt_packet packet;

	packet.type = ppt_pip;
	packet.payload.pip.cr3 = cr3;

	return pt_enc_next(encoder, &packet);
}
Ejemplo n.º 7
0
int pt_encode_mode_exec(struct pt_encoder *encoder, enum pt_exec_mode mode)
{
	struct pt_packet packet;

	packet.type = ppt_mode;
	packet.payload.mode.leaf = pt_mol_exec;
	packet.payload.mode.bits.exec = pt_set_exec_mode(mode);

	return pt_enc_next(encoder, &packet);
}
Ejemplo n.º 8
0
int pt_encode_tnt_64(struct pt_encoder *encoder, uint64_t tnt, int size)
{
	struct pt_packet packet;

	packet.type = ppt_tnt_64;
	packet.payload.tnt.bit_size = (uint8_t) size;
	packet.payload.tnt.payload = tnt;

	return pt_enc_next(encoder, &packet);
}
Ejemplo n.º 9
0
int pt_encode_fup(struct pt_encoder *encoder, uint64_t ip,
		  enum pt_ip_compression ipc)
{
	struct pt_packet packet;

	packet.type = ppt_fup;
	packet.payload.ip.ip = ip;
	packet.payload.ip.ipc = ipc;

	return pt_enc_next(encoder, &packet);
}
Ejemplo n.º 10
0
static struct ptunit_result tma_bad(struct packet_fixture *pfix)
{
	int errcode;

	pfix->packet[0].type = ppt_tma;
	pfix->packet[0].payload.tma.ctc = 0x42;
	pfix->packet[0].payload.tma.fc = 0x200;

	errcode = pt_enc_next(&pfix->encoder, &pfix->packet[0]);
	ptu_int_eq(errcode, -pte_bad_packet);

	return ptu_passed();
}
Ejemplo n.º 11
0
static struct ptunit_result pfix_test(struct packet_fixture *pfix)
{
	int size;

	size = pt_enc_next(&pfix->encoder, &pfix->packet[0]);
	ptu_int_gt(size, 0);

	pfix->packet[0].size = (uint8_t) size;

	size = pt_pkt_next(&pfix->decoder, &pfix->packet[1],
			   sizeof(pfix->packet[1]));
	ptu_int_gt(size, 0);

	return ptu_pkt_eq(&pfix->packet[0], &pfix->packet[1]);
}
Ejemplo n.º 12
0
static struct ptunit_result fetch_packet(struct fetch_fixture *ffix,
					 const struct pt_packet *packet,
					 const struct pt_decoder_function *df)
{
	const struct pt_decoder_function *dfun;
	int errcode;

	errcode = pt_enc_next(&ffix->encoder, packet);
	ptu_int_ge(errcode, 0);

	errcode = pt_df_fetch(&dfun, ffix->config.begin, &ffix->config);
	ptu_int_eq(errcode, 0);
	ptu_ptr_eq(dfun, df);

	return ptu_passed();
}
Ejemplo n.º 13
0
static struct ptunit_result cutoff_cyc(struct packet_fixture *pfix)
{
	int size;

	pfix->packet[0].type = ppt_cyc;
	pfix->packet[0].payload.cyc.value = 0xa8;

	size = pt_enc_next(&pfix->encoder, &pfix->packet[0]);
	ptu_int_gt(size, 0);

	pfix->decoder.config.end = pfix->encoder.pos - 1;

	size = pt_pkt_next(&pfix->decoder, &pfix->packet[1],
			   sizeof(pfix->packet[1]));
	ptu_int_eq(size, -pte_eos);

	return ptu_passed();
}
Ejemplo n.º 14
0
static struct ptunit_result cutoff(struct packet_fixture *pfix,
				   enum pt_packet_type type)
{
	int size;

	pfix->packet[0].type = type;

	size = pt_enc_next(&pfix->encoder, &pfix->packet[0]);
	ptu_int_gt(size, 0);

	pfix->decoder.config.end = pfix->encoder.pos - 1;

	size = pt_pkt_next(&pfix->decoder, &pfix->packet[1],
			   sizeof(pfix->packet[1]));
	ptu_int_eq(size, -pte_eos);

	return ptu_passed();
}
Ejemplo n.º 15
0
int pt_encode_mode_tsx(struct pt_encoder *encoder, uint8_t bits)
{
	struct pt_packet packet;

	packet.type = ppt_mode;
	packet.payload.mode.leaf = pt_mol_tsx;

	if (bits & pt_mob_tsx_intx)
		packet.payload.mode.bits.tsx.intx = 1;
	else
		packet.payload.mode.bits.tsx.intx = 0;

	if (bits & pt_mob_tsx_abrt)
		packet.payload.mode.bits.tsx.abrt = 1;
	else
		packet.payload.mode.bits.tsx.abrt = 0;

	return pt_enc_next(encoder, &packet);
}
Ejemplo n.º 16
0
static struct ptunit_result cutoff_mode(struct packet_fixture *pfix,
					enum pt_mode_leaf leaf)
{
	int size;

	pfix->packet[0].type = ppt_mode;
	pfix->packet[0].payload.mode.leaf = leaf;

	size = pt_enc_next(&pfix->encoder, &pfix->packet[0]);
	ptu_int_gt(size, 0);

	pfix->decoder.config.end = pfix->encoder.pos - 1;

	size = pt_pkt_next(&pfix->decoder, &pfix->packet[1],
			   sizeof(pfix->packet[1]));
	ptu_int_eq(size, -pte_eos);

	return ptu_passed();
}
Ejemplo n.º 17
0
/* Processes the current directive.
 * If the encoder returns an error, a message including current file and
 * line number together with the pt error string is printed on stderr.
 *
 * Returns 0 on success; a negative enum errcode otherwise.
 * Returns -err_internal if @p or @e is the NULL pointer.
 * Returns -err_parse_missing_directive if there was a pt directive marker,
 * but no directive.
 * Returns -stop_process if the .exp directive was encountered.
 * Returns -err_pt_lib if the pt encoder returned an error.
 * Returns -err_parse if a general parsing error was encountered.
 * Returns -err_parse_unknown_directive if there was an unknown pt directive.
 */
static int p_process(struct parser *p, struct pt_encoder *e)
{
	int bytes_written;
	int errcode;
	char *directive, *payload, *pt_label_name, *tmp;
	struct pt_directive *pd;
	struct pt_packet packet;

	if (bug_on(!p))
		return -err_internal;

	if (bug_on(!e))
		return -err_internal;

	pd = p->pd;
	if (!pd)
		return -err_internal;

	directive = pd->name;
	payload = pd->payload;

	pt_label_name = NULL;
	bytes_written = 0;
	errcode = 0;

	/* find a label name.  */
	tmp = strchr(directive, ':');
	if (tmp) {
		uint64_t x;

		pt_label_name = directive;
		directive = tmp+1;
		*tmp = '\0';

		/* ignore whitespace between label and directive. */
		while (isspace(*directive))
			directive += 1;

		/* if we can lookup a yasm label with the same name, the
		 * current pt directive label is invalid.  */
		errcode = yasm_lookup_label(p->y, &x, pt_label_name);
		if (errcode == 0)
			errcode = -err_label_not_unique;

		if (errcode != -err_no_label)
			return yasm_print_err(p->y, "label lookup",
					      errcode);

		/* if we can lookup a pt directive label with the same
		 * name, the current pt directive label is invalid.  */
		errcode = l_lookup(p->pt_labels, &x, pt_label_name);
		if (errcode == 0)
			errcode = -err_label_not_unique;

		if (errcode != -err_no_label)
			return yasm_print_err(p->y, "label lookup",
					      -err_label_not_unique);
	}

	/* now try to match the directive string and call the
	 * corresponding function that parses the payload and emits an
	 * according packet.
	 */
	if (strcmp(directive, "") == 0)
		return yasm_print_err(p->y, "invalid syntax",
				      -err_parse_missing_directive);
	else if (strcmp(directive, ".exp") == 0) {
		/* this is the end of processing pt directives, so we
		 * add a p_last label to the pt directive labels.
		 */
		errcode = l_append(p->pt_labels, "eos", p->pt_bytes_written);
		if (errcode < 0)
			return yasm_print_err(p->y, "append label", errcode);

		return -stop_process;
	}

	if (strcmp(directive, "psb") == 0) {
		errcode = parse_empty(payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "psb: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_psb;
	} else if (strcmp(directive, "psbend") == 0) {
		errcode = parse_empty(payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "psbend: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_psbend;
	} else if (strcmp(directive, "pad") == 0) {
		errcode = parse_empty(payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "pad: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_pad;
	} else if (strcmp(directive, "ovf") == 0) {
		errcode = parse_empty(payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "ovf: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_ovf;
	} else if (strcmp(directive, "tnt") == 0) {
		errcode = parse_tnt(&packet.payload.tnt.payload,
				    &packet.payload.tnt.bit_size, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tnt: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_tnt_8;
	} else if (strcmp(directive, "tnt64") == 0) {
		errcode = parse_tnt(&packet.payload.tnt.payload,
				    &packet.payload.tnt.bit_size, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tnt64: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_tnt_64;
	} else if (strcmp(directive, "tip") == 0) {
		errcode = parse_ip(p, &packet.payload.ip.ip,
				   &packet.payload.ip.ipc, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tip: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_tip;
	} else if (strcmp(directive, "tip.pge") == 0) {
		errcode = parse_ip(p, &packet.payload.ip.ip,
				   &packet.payload.ip.ipc, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tip.pge: parsing failed",
				       errcode);
			goto error;
		}
		packet.type = ppt_tip_pge;
	} else if (strcmp(directive, "tip.pgd") == 0) {
		errcode = parse_ip(p, &packet.payload.ip.ip,
				   &packet.payload.ip.ipc, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tip.pgd: parsing failed",
				       errcode);
			goto error;
		}
		packet.type = ppt_tip_pgd;
	} else if (strcmp(directive, "fup") == 0) {
		errcode = parse_ip(p, &packet.payload.ip.ip,
				   &packet.payload.ip.ipc, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "fup: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_fup;
	} else if (strcmp(directive, "mode.exec") == 0) {
		if (strcmp(payload, "16bit") == 0) {
			packet.payload.mode.bits.exec.csl = 0;
			packet.payload.mode.bits.exec.csd = 0;
		} else if (strcmp(payload, "64bit") == 0) {
			packet.payload.mode.bits.exec.csl = 1;
			packet.payload.mode.bits.exec.csd = 0;
		} else if (strcmp(payload, "32bit") == 0) {
			packet.payload.mode.bits.exec.csl = 0;
			packet.payload.mode.bits.exec.csd = 1;
		} else {
			errcode = yasm_print_err(p->y,
						 "mode.exec: argument must be one of \"16bit\", \"64bit\" or \"32bit\"",
						 -err_parse);
			goto error;
		}
		packet.payload.mode.leaf = pt_mol_exec;
		packet.type = ppt_mode;
	} else if (strcmp(directive, "mode.tsx") == 0) {
		if (strcmp(payload, "begin") == 0) {
			packet.payload.mode.bits.tsx.intx = 1;
			packet.payload.mode.bits.tsx.abrt = 0;
		} else if (strcmp(payload, "abort") == 0) {
			packet.payload.mode.bits.tsx.intx = 0;
			packet.payload.mode.bits.tsx.abrt = 1;
		} else if (strcmp(payload, "commit") == 0) {
			packet.payload.mode.bits.tsx.intx = 0;
			packet.payload.mode.bits.tsx.abrt = 0;
		} else {
			errcode = yasm_print_err(p->y,
						 "mode.tsx: argument must be one of \"begin\", \"abort\" or \"commit\"",
						 -err_parse);
			goto error;
		}
		packet.payload.mode.leaf = pt_mol_tsx;
		packet.type = ppt_mode;
	} else if (strcmp(directive, "pip") == 0) {
		errcode = parse_uint64(&packet.payload.pip.cr3, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "pip: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_pip;
	} else if (strcmp(directive, "tsc") == 0) {
		errcode = parse_uint64(&packet.payload.tsc.tsc, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tsc: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_tsc;
	} else if (strcmp(directive, "cbr") == 0) {
		errcode = parse_uint8(&packet.payload.cbr.ratio, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "cbr: parsing cbr failed",
				       errcode);
			goto error;
		}
		packet.type = ppt_cbr;
	} else {
		errcode = yasm_print_err(p->y, "invalid syntax",
					 -err_parse_unknown_directive);
		goto error;
	}

	bytes_written = pt_enc_next(e, &packet);
	if (bytes_written < 0) {
		const char *errstr, *format;
		char *msg;
		size_t n;

		errstr = pt_errstr(pt_errcode(bytes_written));
		format = "encoder error in directive %s (status %s)";
		/* the length of format includes the "%s" (-2)
		 * characters, we add errstr (+-0) and then we need
		 * space for a terminating null-byte (+1).
		 */
		n = strlen(format)-4 + strlen(directive) + strlen(errstr) + 1;

		msg = malloc(n);
		if (!msg)
			errcode = yasm_print_err(p->y,
				       "encoder error not enough memory to show error code",
				       -err_pt_lib);
		else {
			sprintf(msg, format, directive, errstr);
			errcode = yasm_print_err(p->y, msg, -err_pt_lib);
			free(msg);
		}
	} else {
		if (pt_label_name) {
			errcode = l_append(p->pt_labels, pt_label_name,
					   p->pt_bytes_written);
			if (errcode < 0)
				goto error;
		}
		p->pt_bytes_written += bytes_written;
	}

error:
	if (errcode < 0)
		bytes_written = errcode;
	return bytes_written;
}