[PATCH v2 1/2] Refactor the versioning handling system (code movement)

Kris Van Hees <[email protected]>
Newsgroups dev.linux.lists.dtrace
Message-ID <SJ0PR10MB56720FDBFD11C3DFFF3AD2F9C237A@SJ0PR10MB5672.namprd10.prod.outlook.com>
Consolidate all versioning related code into dt_version.c and
dt_version.h, as a first step to refactoring how versioning info
is managed in the DTrace code base.

Signed-off-by: Kris Van Hees <[email protected]>
---
 libdtrace/Build        |  1 +
 libdtrace/dt_impl.h    | 47 ++++++++-------------
 libdtrace/dt_open.c    | 19 ---------
 libdtrace/dt_subr.c    | 80 -----------------------------------
 libdtrace/dt_version.c | 93 ++++++++++++++++++++++++++++++++++++++++
 libdtrace/dt_version.h | 96 ++++++++++++++++++++++++++++--------------
 6 files changed, 176 insertions(+), 160 deletions(-)
 create mode 100644 libdtrace/dt_version.c

diff --git a/libdtrace/Build b/libdtrace/Build
index b0862ffa0..164023bbc 100644
--- a/libdtrace/Build
+++ b/libdtrace/Build
@@ -69,6 +69,7 @@ libdtrace-build_SOURCES = dt_aggregate.c \
 			  dt_strtab.c \
 			  dt_subr.c \
 			  dt_symtab.c \
+			  dt_version.c \
 			  dt_work.c \
 			  dt_xlator.c
 
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index 1220b211b..7d8e4432a 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -264,8 +264,6 @@ typedef struct dt_percpu_drops {
  */
 #define DT_MAX_NSPECS 16		/* sanity upper bound on speculations */
 
-typedef uint32_t dt_version_t;		/* encoded version (see below) */
-
 struct dtrace_hdl {
 	const dtrace_vector_t *dt_vector; /* library vector, if vectored open */
 	void *dt_varg;	/* vector argument, if vectored open */
@@ -657,6 +655,23 @@ enum {
 	EDT_PRINT,		/* missing or corrupt print() record */
 };
 
+/*
+ * Stability definitions
+ *
+ * These #defines are used in the tables of identifiers below to fill in the
+ * attribute fields associated with each identifier.  The DT_ATTR_* macros are
+ * a convenience to permit more concise declarations of common attributes such
+ * as Stable/Stable/Common.
+ *
+ * Refer to the Solaris Dynamic Tracing Guide Stability chapter respectively
+ * for an explanation of these DTrace features and their values.
+ */
+#define DT_ATTR_STABCMN { DTRACE_STABILITY_STABLE, \
+	DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }
+
+#define DT_ATTR_EVOLCMN { DTRACE_STABILITY_EVOLVING, \
+	DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }
+
 /*
  * Interfaces for parsing and comparing DTrace attribute tuples, which describe
  * stability and architectural binding information.
@@ -666,31 +681,6 @@ extern dtrace_attribute_t dt_attr_max(dtrace_attribute_t, dtrace_attribute_t);
 extern char *dt_attr_str(dtrace_attribute_t, char *, size_t);
 extern int dt_attr_cmp(dtrace_attribute_t, dtrace_attribute_t);
 
-/*
- * Interfaces for parsing and handling DTrace version strings.  Version binding
- * is a feature of the D compiler that is handled completely independently of
- * the DTrace kernel infrastructure, so the definitions are here in libdtrace.
- * Version strings are compiled into an encoded uint32_t which can be compared
- * using C comparison operators.  Version definitions are found in dt_open.c.
- */
-#define	DT_VERSION_STRMAX	16	/* enough for "255.4095.4095\0" */
-#define	DT_VERSION_MAJMAX	0xFF	/* maximum major version number */
-#define	DT_VERSION_MINMAX	0xFFF	/* maximum minor version number */
-#define	DT_VERSION_MICMAX	0xFFF	/* maximum micro version number */
-
-#define	DT_VERSION_NUMBER(M, m, u) \
-	((((M) & 0xFF) << 24) | (((m) & 0xFFF) << 12) | ((u) & 0xFFF))
-
-#define	DT_VERSION_MAJOR(v)	(((v) & 0xFF000000) >> 24)
-#define	DT_VERSION_MINOR(v)	(((v) & 0x00FFF000) >> 12)
-#define	DT_VERSION_MICRO(v)	((v) & 0x00000FFF)
-
-extern char *dt_version_num2str(dt_version_t, char *, size_t);
-extern int dt_version_str2num(const char *, dt_version_t *);
-extern int dt_version_defined(dt_version_t);
-
-extern int dt_str2kver(const char *, dt_version_t *);
-
 extern uint32_t dt_gen_hval(const char *, uint32_t, size_t);
 
 /*
@@ -828,9 +818,6 @@ extern const dtrace_attribute_t _dtrace_typattr; /* type ref attributes */
 extern const dtrace_attribute_t _dtrace_prvattr; /* provider attributes */
 extern const dtrace_pattr_t _dtrace_prvdesc;	 /* provider attribute bundle */
 
-extern const dt_version_t _dtrace_versions[];	 /* array of valid versions */
-extern const char *const _dtrace_version;	 /* current version string */
-
 extern int _dtrace_strbuckets;		/* number of hash buckets for strings */
 extern uint_t _dtrace_stkindent;	/* default indent for stack/ustack */
 extern uint_t _dtrace_pidbuckets;	/* number of hash buckets for pids */
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index c67c33f47..509f263d0 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -44,25 +44,6 @@
 
 #include <dt_git_version.h>
 
-const dt_version_t _dtrace_versions[] = {
-	DT_VERS_1_0,	/* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
-	DT_VERS_1_1,	/* D API 1.1.0 Solaris Express 6/05 */
-	DT_VERS_1_2,	/* D API 1.2.0 Solaris 10 Update 1 */
-	DT_VERS_1_2_1,	/* D API 1.2.1 Solaris Express 4/06 */
-	DT_VERS_1_2_2,	/* D API 1.2.2 Solaris Express 6/06 */
-	DT_VERS_1_3,	/* D API 1.3 Solaris Express 10/06 */
-	DT_VERS_1_4,	/* D API 1.4 Solaris Express 2/07 */
-	DT_VERS_1_4_1,	/* D API 1.4.1 Solaris Express 4/07 */
-	DT_VERS_1_5,	/* D API 1.5 Solaris Express 7/07 */
-	DT_VERS_1_6,	/* D API 1.6 */
-	DT_VERS_1_6_1,	/* D API 1.6.1 */
-	DT_VERS_1_6_2,	/* D API 1.6.2 */
-	DT_VERS_1_6_3,	/* D API 1.6.3 */
-	DT_VERS_1_6_4,	/* D API 1.6.4 */
-	DT_VERS_2_0,	/* D API 2.0 */
-	0
-};
-
 /*
  * Table of global identifiers.  This is used to populate the global identifier
  * hash when a new dtrace client open occurs.  For more info see dt_ident.h.
diff --git a/libdtrace/dt_subr.c b/libdtrace/dt_subr.c
index d5dca1648..40b66c7d6 100644
--- a/libdtrace/dt_subr.c
+++ b/libdtrace/dt_subr.c
@@ -369,58 +369,6 @@ dt_attr_str(dtrace_attribute_t a, char *buf, size_t len)
 	return buf;
 }
 
-char *
-dt_version_num2str(dt_version_t v, char *buf, size_t len)
-{
-	uint_t M = DT_VERSION_MAJOR(v);
-	uint_t m = DT_VERSION_MINOR(v);
-	uint_t u = DT_VERSION_MICRO(v);
-
-	if (u == 0)
-		snprintf(buf, len, "%u.%u", M, m);
-	else
-		snprintf(buf, len, "%u.%u.%u", M, m, u);
-
-	return buf;
-}
-
-int
-dt_version_str2num(const char *s, dt_version_t *vp)
-{
-	int i = 0, n[3] = { 0, 0, 0 };
-	char c;
-
-	while ((c = *s++) != '\0') {
-		if (isdigit(c))
-			n[i] = n[i] * 10 + c - '0';
-		else if (c != '.' || i++ >= sizeof(n) / sizeof(n[0]) - 1)
-			return -1;
-	}
-
-	if (n[0] > DT_VERSION_MAJMAX ||
-	    n[1] > DT_VERSION_MINMAX ||
-	    n[2] > DT_VERSION_MICMAX)
-		return -1;
-
-	if (vp != NULL)
-		*vp = DT_VERSION_NUMBER(n[0], n[1], n[2]);
-
-	return 0;
-}
-
-int
-dt_version_defined(dt_version_t v)
-{
-	int i;
-
-	for (i = 0; _dtrace_versions[i] != 0; i++) {
-		if (_dtrace_versions[i] == v)
-			return 1;
-	}
-
-	return 0;
-}
-
 char *
 dt_cpp_add_arg(dtrace_hdl_t *dtp, const char *str)
 {
@@ -949,34 +897,6 @@ dtrace_uaddr2str(dtrace_hdl_t *dtp, pid_t pid, uint64_t addr, char *str,
 	return dt_string2str(c, str, nbytes);
 }
 
-/*
- * The function converts string representation of kernel version
- * into the dt_version_t type.
- */
-int
-dt_str2kver(const char *kverstr, dt_version_t *vp)
-{
-	int		kv1, kv2, kv3;
-	int		rval;
-
-	rval = sscanf(kverstr, "%d.%d.%d", &kv1, &kv2, &kv3);
-
-	switch (rval) {
-	case 2:
-		kv3 = 0;
-		break;
-	case 3:
-		break;
-	default:
-		return -1;
-	}
-
-	if (vp)
-		*vp = DT_VERSION_NUMBER(kv1, kv2, kv3);
-
-	return 0;
-}
-
 /*
  * Compute a 32-bit hash value for a memory block of given size.
  */
diff --git a/libdtrace/dt_version.c b/libdtrace/dt_version.c
new file mode 100644
index 000000000..e9ac88bea
--- /dev/null
+++ b/libdtrace/dt_version.c
@@ -0,0 +1,93 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include <dt_impl.h>
+
+const dt_version_t _dtrace_versions[] = DTRACE_VERSIONS;
+
+char *
+dt_version_num2str(dt_version_t v, char *buf, size_t len)
+{
+	uint_t	M = DT_VERSION_MAJOR(v);
+	uint_t	m = DT_VERSION_MINOR(v);
+	uint_t	u = DT_VERSION_MICRO(v);
+
+	if (u == 0)
+		snprintf(buf, len, "%u.%u", M, m);
+	else
+		snprintf(buf, len, "%u.%u.%u", M, m, u);
+
+	return buf;
+}
+
+int
+dt_version_str2num(const char *s, dt_version_t *vp)
+{
+	int	i = 0, n[3] = { 0, 0, 0 };
+	char	c;
+
+	while ((c = *s++) != '\0') {
+		if (isdigit(c))
+			n[i] = n[i] * 10 + c - '0';
+		else if (c != '.' || i++ >= ARRAY_SIZE(n) - 1)
+			return -1;
+	}
+
+	if (n[0] > DT_VERSION_MAJMAX ||
+	    n[1] > DT_VERSION_MINMAX ||
+	    n[2] > DT_VERSION_MICMAX)
+		return -1;
+
+	if (vp != NULL)
+		*vp = DT_VERSION_NUMBER(n[0], n[1], n[2]);
+
+	return 0;
+}
+
+int
+dt_version_defined(dt_version_t v)
+{
+	int	i;
+
+	for (i = 0; i < ARRAY_SIZE(_dtrace_versions); i++) {
+		if (_dtrace_versions[i] == v)
+			return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * Convert a string representation of a kernel version string into the
+ * a dt_version_t value.
+ */
+int
+dt_str2kver(const char *kverstr, dt_version_t *vp)
+{
+	int	kv1, kv2, kv3;
+	int	rval;
+
+	rval = sscanf(kverstr, "%d.%d.%d", &kv1, &kv2, &kv3);
+
+	switch (rval) {
+	case 2:
+		kv3 = 0;
+		break;
+	case 3:
+		break;
+	default:
+		return -1;
+	}
+
+	if (vp)
+		*vp = DT_VERSION_NUMBER(kv1, kv2, kv3);
+
+	return 0;
+}
diff --git a/libdtrace/dt_version.h b/libdtrace/dt_version.h
index 290945874..8dd252b08 100644
--- a/libdtrace/dt_version.h
+++ b/libdtrace/dt_version.h
@@ -14,24 +14,6 @@ extern "C" {
 
 #include <dt_ident.h>
 
-/*
- * Stability definitions
- *
- * These #defines are used in the tables of identifiers below to fill in the
- * attribute fields associated with each identifier.  The DT_ATTR_* macros are
- * a convenience to permit more concise declarations of common attributes such
- * as Stable/Stable/Common.
- *
- * Refer to the Solaris Dynamic Tracing Guide Stability chapter respectively
- * for an explanation of these DTrace features and their values.
- */
-#define DT_ATTR_STABCMN { DTRACE_STABILITY_STABLE, \
-	DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }
-
-#define DT_ATTR_EVOLCMN { DTRACE_STABILITY_EVOLVING, \
-	DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON \
-}
-
 /*
  * Versioning definitions
  *
@@ -45,9 +27,11 @@ extern "C" {
  * Refer to the Solaris Dynamic Tracing Guide Versioning chapter for an
  * explanation of these DTrace features and their values.
  *
- * You must update DT_VERS_LATEST and DT_VERS_STRING when adding a new version,
- * and then add the new version to the _dtrace_versions[] array declared in
- * dt_open.c..
+ * When adding a new version:
+ *  - Add a new DT_VERS_* macro
+ *  - Add the new DT_VERS_* macro at the end of the DTRACE_VERSIONS macro
+ *  - Set DT_VERS_LATEST to the new DT_VERS_*
+ *  - Update DT_VERS_STRING to reflect the new version
  *
  * NOTE: Although the DTrace versioning scheme supports the labeling and
  *       introduction of incompatible changes (e.g. dropping an interface in a
@@ -56,16 +40,18 @@ extern "C" {
  *       we ever need to provide divergent interfaces, this will need work.
  *
  * The version number should be increased for every customer visible release
- * of Solaris. The major number should be incremented when a fundamental
- * change has been made that would affect all consumers, and would reflect
- * sweeping changes to DTrace or the D language. The minor number should be
- * incremented when a change is introduced that could break scripts that had
- * previously worked; for example, adding a new built-in variable could break
- * a script which was already using that identifier. The micro number should
- * be changed when introducing functionality changes or major bug fixes that
- * do not affect backward compatibility -- this is merely to make capabilities
- * easily determined from the version number. Minor bugs do not require any
- * modification to the version number.
+ * of DTrace.
+ *  - The major number should be incremented when a fundamental change has been
+ *    made that would affect all consumers, and would reflect sweeping changes
+ *    to DTrace or the D language.
+ *  - The minor number should be incremented when a change is introduced that
+ *    could break scripts that had previously worked; for example, adding a new
+ *    built-in variable could break a script which was already using that
+ *    identifier.
+ *  - The micro number should be changed when introducing functionality changes
+ *    or major bug fixes that do not affect backward compatibility -- this is
+ *    merely to make capabilities easily determined from the version number.
+ *    Minor bugs do not require any modification to the version number.
  */
 #define	DT_VERS_1_0	DT_VERSION_NUMBER(1, 0, 0)
 #define	DT_VERS_1_1	DT_VERSION_NUMBER(1, 1, 0)
@@ -84,9 +70,57 @@ extern "C" {
 #define	DT_VERS_2_0	DT_VERSION_NUMBER(2, 0, 0)
 #define	DT_VERS_2_0_1	DT_VERSION_NUMBER(2, 0, 1)
 
+#define DTRACE_VERSIONS	{ \
+	DT_VERS_1_0,	/* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */ \
+	DT_VERS_1_1,	/* D API 1.1.0 Solaris Express 6/05 */ \
+	DT_VERS_1_2,	/* D API 1.2.0 Solaris 10 Update 1 */ \
+	DT_VERS_1_2_1,	/* D API 1.2.1 Solaris Express 4/06 */ \
+	DT_VERS_1_2_2,	/* D API 1.2.2 Solaris Express 6/06 */ \
+	DT_VERS_1_3,	/* D API 1.3 Solaris Express 10/06 */ \
+	DT_VERS_1_4,	/* D API 1.4 Solaris Express 2/07 */ \
+	DT_VERS_1_4_1,	/* D API 1.4.1 Solaris Express 4/07 */ \
+	DT_VERS_1_5,	/* D API 1.5 Solaris Express 7/07 */ \
+	DT_VERS_1_6,	/* D API 1.6 */ \
+	DT_VERS_1_6_1,	/* D API 1.6.1 */ \
+	DT_VERS_1_6_2,	/* D API 1.6.2 */ \
+	DT_VERS_1_6_3,	/* D API 1.6.3 */ \
+	DT_VERS_1_6_4,	/* D API 1.6.4 */ \
+	DT_VERS_2_0,	/* D API 2.0 */ \
+}
+
 #define	DT_VERS_LATEST	DT_VERS_2_0_1
 #define	DT_VERS_STRING	"Oracle D 2.0"
 
+/*
+ * Interfaces for parsing and handling DTrace version strings.  Version binding
+ * is a feature of the D compiler that is handled completely independently of
+ * the DTrace kernel infrastructure, so the definitions are here in libdtrace.
+ * Version strings are compiled into an encoded uint32_t which can be compared
+ * using C comparison operators.
+ */
+#define	DT_VERSION_STRMAX	16	/* enough for "255.4095.4095\0" */
+#define	DT_VERSION_MAJMAX	0xFF	/* maximum major version number */
+#define	DT_VERSION_MINMAX	0xFFF	/* maximum minor version number */
+#define	DT_VERSION_MICMAX	0xFFF	/* maximum micro version number */
+
+#define	DT_VERSION_NUMBER(M, m, u) \
+	((((M) & 0xFF) << 24) | (((m) & 0xFFF) << 12) | ((u) & 0xFFF))
+
+#define	DT_VERSION_MAJOR(v)	(((v) & 0xFF000000) >> 24)
+#define	DT_VERSION_MINOR(v)	(((v) & 0x00FFF000) >> 12)
+#define	DT_VERSION_MICRO(v)	((v) & 0x00000FFF)
+
+typedef uint32_t dt_version_t;
+
+extern const dt_version_t _dtrace_versions[];
+extern const char *const _dtrace_version;
+
+extern char *dt_version_num2str(dt_version_t, char *, size_t);
+extern int dt_version_str2num(const char *, dt_version_t *);
+extern int dt_version_defined(dt_version_t);
+
+extern int dt_str2kver(const char *, dt_version_t *);
+
 #ifdef  __cplusplus
 }
 #endif
-- 
2.45.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.