Existing symbol versioning macros are not suitable for versioning exported global variables.
Specifically, if existing macros are used for versioning global variable symbol promoted from experimental to stable, result would be multiple variables with separate storage defined. If an application was linked against older DPDK and had copy relocations, this would yield an inconsistent behavior: - Application would use experimental symbol version, with storage set up in BSS section in application. - Library would use latest symbol version, with storage set up in BSS section of shared object. This patch adds versioning macros which utilize symbol aliasing. Specifically, a new variable (with version suffix) is defined as an alias to private (static) variable inside the library. Variable symbol versions are attached to these alias variables. Following macros are added: - RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS - RTE_DEFAULT_SYMBOL_ALIAS Signed-off-by: Dariusz Sosnowski <[email protected]> --- buildtools/gen-version-map.py | 11 +++++++++++ lib/eal/common/eal_export.h | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/buildtools/gen-version-map.py b/buildtools/gen-version-map.py index 57e08a8c0f..aa88e69179 100755 --- a/buildtools/gen-version-map.py +++ b/buildtools/gen-version-map.py @@ -14,8 +14,12 @@ export_int_sym_regexp = re.compile(r"^RTE_EXPORT_INTERNAL_SYMBOL\(([^)]+)\)") export_sym_regexp = re.compile(r"^RTE_EXPORT_SYMBOL\(([^)]+)\)") ver_sym_regexp = re.compile(r"^RTE_VERSION_SYMBOL\(([^,]+), [^,]+, ([^,]+),") + ver_exp_sym_regexp = re.compile(r"^RTE_VERSION_EXPERIMENTAL_SYMBOL\([^,]+, ([^,]+),") +ver_exp_sym_alias_regexp = re.compile(r"^RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS\([^,]+, ([^,]+),") + default_sym_regexp = re.compile(r"^RTE_DEFAULT_SYMBOL\(([^,]+), [^,]+, ([^,]+),") +default_sym_alias_regexp = re.compile(r"^RTE_DEFAULT_SYMBOL_ALIAS\(([^,]+), [^,]+, ([^,]+),") parser = argparse.ArgumentParser( description=__doc__, @@ -73,10 +77,17 @@ elif ver_exp_sym_regexp.match(ln): node = "EXPERIMENTAL" symbol = ver_exp_sym_regexp.match(ln).group(1) + elif ver_exp_sym_alias_regexp.match(ln): + node = "EXPERIMENTAL" + symbol = ver_exp_sym_alias_regexp.match(ln).group(1) elif default_sym_regexp.match(ln): abi = default_sym_regexp.match(ln).group(1) node = f"DPDK_{abi}" symbol = default_sym_regexp.match(ln).group(2) + elif default_sym_alias_regexp.match(ln): + abi = default_sym_alias_regexp.match(ln).group(1) + node = f"DPDK_{abi}" + symbol = default_sym_alias_regexp.match(ln).group(2) if not symbol: continue diff --git a/lib/eal/common/eal_export.h b/lib/eal/common/eal_export.h index 7971bf8d7a..5b458f81c6 100644 --- a/lib/eal/common/eal_export.h +++ b/lib/eal/common/eal_export.h @@ -63,6 +63,14 @@ __attribute__((__symver__(RTE_STR(name) "@@DPDK_" RTE_STR(ver)))) \ type name ## _v ## ver args; \ type name ## _v ## ver args +#define RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS(type, name, orig) VERSIONING_WARN \ +extern type name ## _exp __attribute((alias(RTE_STR(orig)), \ + __symver__(RTE_STR(name) "@EXPERIMENTAL"))) + +#define RTE_DEFAULT_SYMBOL_ALIAS(ver, type, name, orig) VERSIONING_WARN \ +extern type name ## _v ## ver __attribute((alias(RTE_STR(orig)), \ + __symver__(RTE_STR(name) "@@DPDK_" RTE_STR(ver)))) + #else /* !__has_attribute(symver) */ /* Use asm tag to create symbol table entry */ @@ -81,6 +89,14 @@ __asm__(".symver " RTE_STR(name) "_v" RTE_STR(ver) ", " RTE_STR(name) "@@DPDK_" __rte_used type name ## _v ## ver args; \ type name ## _v ## ver args +#define RTE_DEFAULT_SYMBOL_ALIAS(ver, type, name, orig) VERSIONING_WARN \ +extern type name ## _v ## ver __attribute__((alias(RTE_STR(orig)))); \ +__asm__(".symver " RTE_STR(name) "_v" RTE_STR(ver) ", " RTE_STR(name) "@@DPDK_" RTE_STR(ver)); + +#define RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS(type, name, orig) VERSIONING_WARN \ +extern type name ## _exp __attribute__((alias(RTE_STR(orig)))); \ +__asm__(".symver " RTE_STR(name) "_exp, " RTE_STR(name) "@EXPERIMENTAL"); + #endif /* __has_attribute(symver) */ #else /* !RTE_BUILD_SHARED_LIB */ @@ -97,6 +113,12 @@ type name ## _exp args #define RTE_DEFAULT_SYMBOL(ver, type, name, args) VERSIONING_WARN \ type name args +#define RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS(type, name, orig) VERSIONING_WARN \ +extern type name ## _exp __attribute__((alias(RTE_STR(orig)))); + +#define RTE_DEFAULT_SYMBOL_ALIAS(ver, type, name, orig) VERSIONING_WARN \ +extern type name __attribute__((alias(RTE_STR(orig)))); + #endif /* RTE_BUILD_SHARED_LIB */ #endif /* EAL_EXPORT_H */ -- 2.47.3

