[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