ptxed: support truncated blocks

A block of instructions may be marked truncated if the last instruction in the
block can not be read entirely from the block's section.  It is instead provided
in the block itself.

Use the memory provided in the block in that case.

Our test system needs a few changes before we can write a test for this.

Change-Id: Ic9fcec2d32a908b13c8531ff2f6c0823241afefe
Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
diff --git a/ptxed/src/ptxed.c b/ptxed/src/ptxed.c
index d5eca19..b656dcd 100644
--- a/ptxed/src/ptxed.c
+++ b/ptxed/src/ptxed.c
@@ -728,15 +728,25 @@
 	for (; block->ninsn; --block->ninsn) {
 		xed_decoded_inst_t inst;
 		xed_error_enum_t xederrcode;
-		uint8_t raw[pt_max_insn_size];
+		uint8_t raw[pt_max_insn_size], *praw;
 		int size, errcode;
 
-		size = pt_iscache_read(iscache, raw, sizeof(raw), block->isid,
-				       block->ip);
-		if (size < 0) {
-			printf(" [error reading insn: (%d) %s]\n", size,
-			       pt_errstr(pt_errcode(size)));
-			break;
+		/* For truncated block, the last instruction is provided in the
+		 * block since it can't be read entirely from the image section
+		 * cache.
+		 */
+		if (block->truncated && (block->ninsn == 1)) {
+			praw = block->raw;
+			size = block->size;
+		} else {
+			praw = raw;
+			size = pt_iscache_read(iscache, raw, sizeof(raw),
+					       block->isid, block->ip);
+			if (size < 0) {
+				printf(" [error reading insn: (%d) %s]\n", size,
+				       pt_errstr(pt_errcode(size)));
+				break;
+			}
 		}
 
 		xed_decoded_inst_zero_set_mode(&inst, &xed);
@@ -749,7 +759,7 @@
 
 		printf("%016" PRIx64, block->ip);
 
-		xederrcode = xed_decode(&inst, raw, size);
+		xederrcode = xed_decode(&inst, praw, size);
 		if (xederrcode != XED_ERROR_NONE) {
 			printf(" [xed decode error: (%u) %s]\n", xederrcode,
 			       xed_error_enum_t2str(xederrcode));