From 2a62be5f20707d350e9be6406a853ecdf4be4051 Mon Sep 17 00:00:00 2001
From: Yogesh Tyagi <yogesh.tyagi@intel.com>
Date: Sun, 1 Feb 2026 22:54:34 +0800
Subject: [PATCH] pttc: Add support for nasm assembler

Replace yasm with nasm as the default assembler for pttc. Yasm is no
longer actively maintained and has known security vulnerabilities, while
nasm is actively developed and provides equivalent functionality.

Key changes:
1. Update assembler invocation from 'yasm' to 'nasm'
2. Remove '-L nasm' option (nasm doesn't need this flag)
3. Adjust argv array indices after removing the flag
4. Support both yasm and nasm org directive formats:
   - yasm: [org 0x100000]
   - nasm: org 0x100000
5. Handle nasm's listing format which lacks %line directives by
   implementing 1:1 line mapping fallback for source correlation

The changes maintain backward compatibility with existing .ptt test files
while enabling nasm as the preferred assembler.

Tested with:
- test/src/loop-tnt.ptt
- test/src/dump-all-packets.ptt

Both tests generate valid PT traces that can be decoded with ptdump.

Upstream-Status: Submitted [https://github.com/intel/libipt/pull/120]

Signed-off-by: Yogesh Tyagi <yogesh.tyagi@intel.com>
---
 doc/howto_pttc.md |  6 ++---
 pttc/src/yasm.c   | 63 +++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 56 insertions(+), 13 deletions(-)

diff --git a/doc/howto_pttc.md b/doc/howto_pttc.md
index e7308cdb..c356103b 100644
--- a/doc/howto_pttc.md
+++ b/doc/howto_pttc.md
@@ -31,7 +31,7 @@ Testing the Intel(R) Processor Trace (Intel PT) Decoder Library and Samples {#pt
  !-->
 
 This chapter documents how to use the pttc tool to generate and run tests.
-Pttc takes a yasm assembly file and creates a Processor Trace stream from
+Pttc takes a nasm assembly file and creates a Processor Trace stream from
 special directives in its input.
 
 
@@ -49,7 +49,7 @@ directory:
 	file-<tool>.exp
 	file-<src>.sb
 
-The `.lst` and `.bin` files are generated by a call to yasm. The `.pt` file
+The `.lst` and `.bin` files are generated by a call to nasm. The `.pt` file
 contains the Processor Trace and the `.exp` files contain the content of the
 comments after the `.exp` directive for tool `<tool>` (see below).  The `.sb`
 files contain sideband infomrmation from source `<src>` (see below).
@@ -60,7 +60,7 @@ Pttc prints the filenames of the generated `.exp` and `.sb` files to stdout.
 Syntax
 ------
 
-Pttc allows annotations in the comments of yasm assembler source files.  The
+Pttc allows annotations in the comments of nasm assembler source files.  The
 parser recognizes all comments that contain the `@pt` directive marker.
 
 Every pt directive can be preceded by a label name followed by a colon (`:`).
diff --git a/pttc/src/yasm.c b/pttc/src/yasm.c
index 2f3020d1..98f6d846 100644
--- a/pttc/src/yasm.c
+++ b/pttc/src/yasm.c
@@ -155,7 +155,7 @@ static int lookup_section_vstart(struct label *l, char *line,
 }
 
 static const char key_section[] = "[section";
-static const char key_org[] = "[org";
+static const char *key_org[] = {"[org", "org", NULL};
 
 int parse_yasm_labels(struct label *l, const struct text *t)
 {
@@ -192,12 +192,33 @@ int parse_yasm_labels(struct label *l, const struct text *t)
 			continue;
 		}
 
-		tmp = strstr(line, key_org);
-		if (tmp) {
+		/* Try both yasm format "[org" and nasm format "org" */
+		tmp = NULL;
+		int org_style = -1;
+		for (int j = 0; key_org[j] != NULL; j++) {
+			tmp = strstr(line, key_org[j]);
+			if (tmp) {
+				org_style = j;
+				break;
+			}
+		}
+
+		if (tmp && org_style >= 0) {
 			char *org;
 
-			org = tmp + sizeof(key_org) - 1;
-			tmp = strstr(org, "]");
+			org = tmp + strlen(key_org[org_style]);
+			/* For yasm format "[org", look for ] */
+			if (org_style == 0) {
+				tmp = strstr(org, "]");
+			} else {
+				/* For nasm, skip whitespace to find hex value */
+				while (isspace(*org))
+					org++;
+				tmp = org;
+				/* Find end of hex number */
+				while (*tmp && !isspace(*tmp))
+					tmp++;
+			}
 			if (!tmp)
 				return -err_no_org_directive;
 
@@ -720,18 +741,17 @@ error:
 static int yasm_run(struct yasm *y)
 {
 	char *argv[] = {
-		"yasm",
+		"nasm",
 		"<pttfile>",
 		"-f", "bin",
 		"-o", "<binfile>",
-		"-L", "nasm",
 		"-l", "<lstfile>",
 		NULL,
 	};
 
 	argv[1] = y->pttfile;
 	argv[5] = y->binfile;
-	argv[9] = y->lstfile;
+	argv[7] = y->lstfile;
 
 	return run(argv[0], argv);
 }
@@ -825,9 +845,32 @@ static int yasm_advance_next_line(struct yasm *y)
 		/* if line number or increment in the previous line
 		 * directive is <= 0, the current lst line has no
 		 * corresponding line in the source file.
+		 * 
+		 * For nasm compatibility: if no %line directives have been
+		 * seen yet, assume 1:1 mapping with source file.
 		 */
-		if (y->st_asm->n <= 0 || y->st_asm->inc <= 0)
-			continue;
+		if (y->st_asm->n <= 0 || y->st_asm->inc <= 0) {
+			/* If we haven't seen any %line directive, try to use
+			 * the source file directly with 1:1 line mapping.
+			 */
+			if (!y->st_asm->filename || y->st_asm->filename[0] == '\0') {
+				/* Set to source .ptt file for first time */
+				st_set_file(y->st_asm, y->pttfile, 1, 1);
+			}
+			
+			/* Calculate source line from listing line for nasm */
+			asm_line = (int)y->lst_curr_line;
+			
+			/* Read from source file at same line number */
+			errcode = fl_getline(y->fl, s, (size_t) sizeof(s),
+					     y->st_asm->filename,
+					     (size_t) asm_line - 1u);
+			if (errcode < 0)
+				continue;  /* Skip if can't read source line */
+
+			errcode = st_update(y->st_asm, s);
+			break;
+		}
 
 		/* finally the current line in the lst file can be
 		 * correlated to the source file, so we retrieve the
-- 
2.34.1

