From 8ae9a335d56fc4aba8454159b326d809efca597f Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Mon, 11 Aug 2025 21:13:59 -0700
Subject: [PATCH] Add conditional version script support

This patch adds conditional symbol versioning to libtirpc, allowing
GSS-API, DES crypto, and RPC database symbols to be conditionally
included in the version script based on build configuration.

LLD is strict about undefined symbols referenced in a version script.
Some libtirpc symbols (rpcsec_gss, old DES helpers, rpc database
helpers) are optional and may not be built depending on configure
options or missing deps. GNU ld tolerated this; LLD errors out.

This change keeps the canonical symbol map in src/libtirpc.map, but
adds a make-time rule to generate a filtered copy
where names from disabled features are deleted. The lib is then linked
against the generated linker map file.

Fixes linking errors when these features are not available.

Upstream-Status: Submitted [https://lore.kernel.org/linux-nfs/20250812180809.2182301-1-raj.khem@gmail.com/T/#u]
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
 configure.ac                          | 50 +++++++++++++++++++++++++++
 src/Makefile.am                       | 21 +++++++++--
 src/{libtirpc.map => libtirpc.map.in} | 48 +++++--------------------
 3 files changed, 77 insertions(+), 42 deletions(-)
 rename src/{libtirpc.map => libtirpc.map.in} (84%)

--- a/configure.ac
+++ b/configure.ac
@@ -77,6 +77,19 @@ if test "x$enable_ipv6" != xno; then
 	AC_DEFINE(INET6, 1, [Define to 1 if IPv6 is available])
 fi
 
+# RPC database support
+AC_ARG_ENABLE(rpcdb,
+    [AS_HELP_STRING([--enable-rpcdb], [Enable RPC Database support @<:@default=no@:>@])],
+    [], [enable_rpcdb=no])
+AM_CONDITIONAL(RPCDB, test "x$enable_rpcdb" = xyes)
+if test "x$enable_rpcdb" != "xno"; then
+    AC_CHECK_FUNCS([getrpcent getrpcbyname getrpcbynumber], [have_rpcdb=yes])
+
+    if test "x$have_rpcdb" = "xyes"; then
+        AC_DEFINE([RPCDB], [1], [Define if RPC database support is available])
+    fi
+fi
+
 AC_ARG_ENABLE(symvers,
 	[AS_HELP_STRING([--disable-symvers],[Disable symbol versioning @<:@default=no@:>@])],
       [],[enable_symvers=maybe])
@@ -97,6 +110,33 @@ fi
 
 AM_CONDITIONAL(SYMVERS, test "x$enable_symvers" = xyes)
 
+# Generate symbol lists for version script
+if test "x$enable_gssapi" = "xyes"; then
+    GSS_SYMBOLS="_svcauth_gss; authgss_create; authgss_create_default; authgss_free_private_data; authgss_get_private_data; authgss_service; gss_log_debug; gss_log_hexdump; gss_log_status; rpc_gss_get_error; rpc_gss_get_mech_info; rpc_gss_get_mechanisms; rpc_gss_get_principal_name; rpc_gss_get_versions; rpc_gss_qop_to_num; rpc_gss_seccreate; rpc_gss_set_callback; rpc_gss_set_defaults; rpc_gss_set_svc_name; rpc_gss_svc_max_data_length;"
+
+    GSS_SYMBOLS_031="svcauth_gss_get_principal; svcauth_gss_set_svc_name;"
+else
+    GSS_SYMBOLS=""
+    GSS_SYMBOLS_031=""
+fi
+
+if test "x$enable_authdes" = "xyes"; then
+    DES_SYMBOLS="cbc_crypt; ecb_crypt; xdr_authdes_cred; xdr_authdes_verf; xdr_rpc_gss_cred; xdr_rpc_gss_data; xdr_rpc_gss_init_args; xdr_rpc_gss_init_res;"
+else
+    DES_SYMBOLS=""
+fi
+
+if test "x$enable_rpcdb" = "xyes"; then
+    RPCDB_SYMBOLS="endrpcent; getrpcent; getrpcbynumber; getrpcbyname; setrpcent;"
+else
+    RPCDB_SYMBOLS=""
+fi
+
+AC_SUBST([GSS_SYMBOLS])
+AC_SUBST([GSS_SYMBOLS_031])
+AC_SUBST([DES_SYMBOLS])
+AC_SUBST([RPCDB_SYMBOLS])
+
 AC_CANONICAL_BUILD
 # Check for which host we are on and setup a few things
 # specifically based on the host
@@ -167,7 +207,16 @@ AC_CHECK_FUNCS([getpeereid getrpcbyname
 AC_CHECK_TYPES(struct rpcent,,, [
       #include <netdb.h>])
 AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile])
+AC_CONFIG_FILES([src/libtirpc.map])
 AC_CONFIG_FILES([libtirpc.pc])
 AC_OUTPUT
 
+# Configuration summary
+AC_MSG_NOTICE([
+libtirpc configuration summary:
+  GSS-API support: $enable_gssapi
+  DES crypto support: $enable_authdes
+  RPC database support: $enable_rpcdb
+  Symbol versioning: $enable_symvers
+])
 
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,6 +6,9 @@
 ## anything like that.
 
 noinst_HEADERS = rpc_com.h debug.h
+EXTRA_DIST = libtirpc.map.in
+# Generated files
+BUILT_SOURCES = libtirpc.map
 
 AM_CPPFLAGS = -I$(top_srcdir)/tirpc -include config.h -DPORTMAP -DINET6 \
 		-D_GNU_SOURCE -Wall -pipe
@@ -15,10 +18,19 @@ lib_LTLIBRARIES = libtirpc.la
 libtirpc_la_LDFLAGS = @LDFLAG_NOUNDEFINED@ -no-undefined @PTHREAD_LIBS@
 libtirpc_la_LDFLAGS += -version-info @LT_VERSION_INFO@
 
+# Generate version script from template
+libtirpc.map: $(srcdir)/libtirpc.map.in
+	$(AM_V_GEN)$(SED) \
+		-e 's|@GSS_SYMBOLS@|$(GSS_SYMBOLS)|g' \
+		-e 's|@GSS_SYMBOLS_031@|$(GSS_SYMBOLS_031)|g' \
+		-e 's|@DES_SYMBOLS@|$(DES_SYMBOLS)|g' \
+		-e 's|@RPCDB_SYMBOLS@|$(RPCDB_SYMBOLS)|g' \
+		< $(srcdir)/libtirpc.map.in > $@ || rm -f $@
+
 libtirpc_la_SOURCES = auth_none.c auth_unix.c authunix_prot.c \
         binddynport.c bindresvport.c \
         clnt_bcast.c clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \
-        clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c getrpcent.c \
+        clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c \
         getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \
         pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \
         rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \
@@ -34,19 +46,23 @@ endif
 libtirpc_la_SOURCES += xdr.c xdr_rec.c xdr_array.c xdr_float.c xdr_mem.c xdr_reference.c xdr_stdio.c xdr_sizeof.c
 
 if SYMVERS
-    libtirpc_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libtirpc.map
+    libtirpc_la_LDFLAGS += -Wl,--version-script=$(builddir)/libtirpc.map
 endif
 
 ## Secure-RPC
 if GSS
-    libtirpc_la_SOURCES += auth_gss.c authgss_prot.c svc_auth_gss.c \
-			   rpc_gss_utils.c
-    libtirpc_la_LIBADD = $(GSSAPI_LIBS)
-    libtirpc_la_CFLAGS = -DHAVE_RPCSEC_GSS $(GSSAPI_CFLAGS)
+libtirpc_la_SOURCES += auth_gss.c authgss_prot.c svc_auth_gss.c rpc_gss_utils.c
+libtirpc_la_LIBADD = $(GSSAPI_LIBS)
+libtirpc_la_CFLAGS = -DHAVE_RPCSEC_GSS $(GSSAPI_CFLAGS)
+endif
+
+# Conditionally add RPC database sources
+if RPCDB
+libtirpc_la_SOURCES += getrpcent.c
 endif
 
 libtirpc_la_SOURCES += key_call.c key_prot_xdr.c getpublickey.c
 libtirpc_la_SOURCES += netname.c netnamer.c rpcdname.c rtime.c
 
-CLEANFILES	       = cscope.* *~
+CLEANFILES	       = cscope.* libtirpc.map *~
 DISTCLEANFILES	       = Makefile.in
--- a/src/libtirpc.map
+++ /dev/null
@@ -1,335 +0,0 @@
-TIRPC_0.3.0 {
-  global:
-    # __*
-    __rpc_createerr;
-    __rpc_dtbsize;
-    __rpc_endconf;
-    __rpc_fd2sockinfo;
-    __rpc_fixup_addr;
-    __rpc_get_a_size;
-    __rpc_get_local_uid;
-    __rpc_get_t_size;
-    __rpc_getconf;
-    __rpc_getconfip;
-    __rpc_nconf2fd;
-    __rpc_nconf2fd_flags;
-    __rpc_nconf2sockinfo;
-    __rpc_rawcombuf;
-    __rpc_seman2socktype;
-    __rpc_setconf;
-    __rpc_sockinfo2netid;
-    __rpc_sockisbound;
-    __rpc_socktype2seman;
-    __rpc_taddr2uaddr_af;
-    __rpc_uaddr2taddr_af;
-    __rpcgettp;
-
-    # _*
-    _authenticate;
-    _get_next_token;
-    _gss_authenticate;
-    _null_auth;
-    _rpc_dtablesize;
-    _seterr_reply;
-    _svcauth_none;
-    _svcauth_short;
-    _svcauth_unix;
-    _svcauth_gss;
-
-    # a*
-    authdes_create;
-    authdes_seccreate;
-    authgss_create;
-    authgss_create_default;
-    authgss_free_private_data;
-    authgss_get_private_data;
-    authgss_service;
-    authnone_create;
-    authunix_create;
-    authunix_create_default;
-
-    # b*
-    bindresvport;
-    bindresvport_sa;
-
-    # c*
-    callrpc;
-    cbc_crypt;
-    clnt_broadcast;
-    clnt_create;
-    clnt_create_timed;
-    clnt_create_vers;
-    clnt_create_vers_timed;
-    clnt_dg_create;
-    clnt_pcreateerror;
-    clnt_perrno;
-    clnt_perror;
-    clnt_raw_create;
-    clnt_spcreateerror;
-    clnt_sperrno;
-    clnt_sperror;
-    clnt_tli_create;
-    clnt_tp_create;
-    clnt_tp_create_timed;
-    clnt_vc_create;
-    clntraw_create;
-    clnttcp_create;
-    clntudp_bufcreate;
-    clntudp_create;
-    clntunix_create;
-
-    # e*
-    ecb_crypt;
-    endnetconfig;
-    endnetpath;
-    endrpcent;
-
-    # f*
-    freenetconfigent;
-
-    # g*
-    get_myaddress;
-    getnetconfig;
-    getnetconfigent;
-    getnetpath;
-    getrpcent;
-    getrpcbynumber;
-    getrpcbyname;
-    getrpcport;
-    gss_log_debug;
-    gss_log_hexdump;
-    gss_log_status;
-
-    # n*
-    nc_perror;
-    nc_sperror;
-
-    # p*
-    pmap_getmaps;
-    pmap_getport;
-    pmap_rmtcall;
-    pmap_set;
-    pmap_unset;
-
-    # r*
-    registerrpc;
-    rpc_broadcast;
-    rpc_broadcast_exp;
-    rpc_call;
-    rpc_control;
-    rpc_createerr;
-    rpc_gss_get_error;
-    rpc_gss_get_mech_info;
-    rpc_gss_get_mechanisms;
-    rpc_gss_get_principal_name;
-    rpc_gss_get_versions;
-    rpc_gss_getcred;
-    rpc_gss_is_installed;
-    rpc_gss_max_data_length;
-    rpc_gss_mech_to_oid;
-    rpc_gss_qop_to_num;
-    rpc_gss_seccreate;
-    rpc_gss_set_callback;
-    rpc_gss_set_defaults;
-    rpc_gss_set_svc_name;
-    rpc_gss_svc_max_data_length;
-    rpc_nullproc;
-    rpc_reg;
-    rpcb_getaddr;
-    rpcb_getmaps;
-    rpcb_gettime;
-    rpcb_rmtcall;
-    rpcb_set;
-    rpcb_taddr2uaddr;
-    rpcb_uaddr2taddr;
-    rpcb_unset;
-
-    # s*
-    setnetconfig;
-    setnetpath;
-    setrpcent;
-    svc_auth_reg;
-    svc_create;
-    svc_dg_create;
-    svc_dg_enablecache;
-    svc_exit;
-    svc_fd_create;
-    svc_fdset;
-    svc_getreq;
-    svc_getreq_common;
-    svc_getreq_poll;
-    svc_getreqset;
-    svc_maxfd;
-    svc_raw_create;
-    svc_reg;
-    svc_register;
-    svc_run;
-    svc_sendreply;
-    svc_tli_create;
-    svc_tp_create;
-    svc_unreg;
-    svc_unregister;
-    svc_vc_create;
-    svcerr_auth;
-    svcerr_decode;
-    svcerr_noproc;
-    svcerr_noprog;
-    svcerr_progvers;
-    svcerr_systemerr;
-    svcerr_weakauth;
-    svcfd_create;
-    svcraw_create;
-    svctcp_create;
-    svcudp_bufcreate;
-    svcudp_create;
-    svcunix_create;
-    svcunixfd_create;
-
-    # t*
-    taddr2uaddr;
-
-    # u*
-    uaddr2taddr;
-
-    # x*
-    xdr_accepted_reply;
-    xdr_array;
-    xdr_authdes_cred;
-    xdr_authdes_verf;
-    xdr_authunix_parms;
-    xdr_bool;
-    xdr_bytes;
-    xdr_callhdr; xdr_callmsg;
-    xdr_char;
-    xdr_des_block;
-    xdr_double;
-    xdr_enum;
-    xdr_float;
-    xdr_free;
-    xdr_hyper;
-    xdr_int16_t;
-    xdr_int32_t;
-    xdr_int64_t;
-    xdr_int8_t;
-    xdr_int;
-    xdr_long;
-    xdr_longlong_t;
-    xdr_netbuf;
-    xdr_netobj;
-    xdr_opaque;
-    xdr_opaque_auth;
-    xdr_pmap;
-    xdr_pmaplist;
-    xdr_pmaplist_ptr;
-    xdr_pointer;
-    xdr_quad_t;
-    xdr_reference;
-    xdr_rejected_reply;
-    xdr_replymsg;
-    xdr_rmtcall_args;
-    xdr_rmtcallres;
-    xdr_rpc_gss_cred;
-    xdr_rpc_gss_data;
-    xdr_rpc_gss_init_args;
-    xdr_rpc_gss_init_res;
-    xdr_rpcb;
-    xdr_rpcb_entry;
-    xdr_rpcb_entry_list_ptr;
-    xdr_rpcb_rmtcallargs;
-    xdr_rpcb_rmtcallres;
-    xdr_rpcb_stat;
-    xdr_rpcb_stat_byvers;
-    xdr_rpcblist;
-    xdr_rpcblist_ptr;
-    xdr_rpcbs_addrlist;
-    xdr_rpcbs_addrlist_ptr;
-    xdr_rpcbs_proc;
-    xdr_rpcbs_rmtcalllist;
-    xdr_rpcbs_rmtcalllist_ptr;
-    xdr_short;
-    xdr_string;
-    xdr_u_char;
-    xdr_u_hyper;
-    xdr_u_int16_t;
-    xdr_u_int32_t;
-    xdr_u_int64_t;
-    xdr_u_int8_t;
-    xdr_u_int;
-    xdr_u_long;
-    xdr_u_longlong_t;
-    xdr_u_quad_t;
-    xdr_u_short;
-    xdr_uint16_t;
-    xdr_uint32_t;
-    xdr_uint64_t;
-    xdr_uint8_t;
-    xdr_union;
-    xdr_vector;
-    xdr_void;
-    xdr_wrapstring;
-    xdrmem_create;
-    xdrrec_create;
-    xdrrec_endofrecord;
-    xdrrec_eof;
-    xdrrec_skiprecord;
-    xdrstdio_create;
-    xprt_register;
-    xprt_unregister;
-
-  local:
-    *;
-};
-
-TIRPC_0.3.1 {
-    svcauth_gss_get_principal;
-    svcauth_gss_set_svc_name;
-} TIRPC_0.3.0;
-
-TIRPC_0.3.2 {
-    getnetname;
-    getpublicandprivatekey;
-    getpublickey;
-    host2netname;
-    key_call_destroy;
-    key_decryptsession;
-    key_decryptsession_pk;
-    key_encryptsession;
-    key_encryptsession_pk;
-    key_gendes;
-    key_get_conv;
-    key_setsecret;
-    key_secretkey_is_set;
-    key_setnet;
-    netname2host;
-    netname2user;
-    rtime;
-    user2netname;
-    xdr_cryptkeyarg;
-    xdr_cryptkeyarg2;
-    xdr_cryptkeyres;
-    xdr_getcredres;
-    xdr_key_netstarg;
-    xdr_key_netstres;
-    xdr_keybuf;
-    xdr_keystatus;
-    xdr_netnamestr;
-    xdr_unixcred;
-} TIRPC_0.3.1;
-
-TIRPC_0.3.3 {
-    __getpublickey_LOCAL;
-    __key_decryptsession_pk_LOCAL;
-    __key_encryptsession_pk_LOCAL;
-    __key_gendes_LOCAL;
-    xdr_sizeof;
-    authdes_pk_create;
-    svc_pollfd;
-    svc_max_pollfd;
-} TIRPC_0.3.2;
-
-TIRPC_PRIVATE {
-  global:
-    __libc_clntudp_bufcreate;
-  # private, but used by rpcbind:
-    __svc_clean_idle; svc_auth_none; libtirpc_set_debug;
-};
--- /dev/null
+++ b/src/libtirpc.map.in
@@ -0,0 +1,303 @@
+TIRPC_0.3.0 {
+  global:
+    # __*
+    __rpc_createerr;
+    __rpc_dtbsize;
+    __rpc_endconf;
+    __rpc_fd2sockinfo;
+    __rpc_fixup_addr;
+    __rpc_get_a_size;
+    __rpc_get_local_uid;
+    __rpc_get_t_size;
+    __rpc_getconf;
+    __rpc_getconfip;
+    __rpc_nconf2fd;
+    __rpc_nconf2fd_flags;
+    __rpc_nconf2sockinfo;
+    __rpc_rawcombuf;
+    __rpc_seman2socktype;
+    __rpc_setconf;
+    __rpc_sockinfo2netid;
+    __rpc_sockisbound;
+    __rpc_socktype2seman;
+    __rpc_taddr2uaddr_af;
+    __rpc_uaddr2taddr_af;
+    __rpcgettp;
+
+    # _*
+    _authenticate;
+    _get_next_token;
+    _gss_authenticate;
+    _null_auth;
+    _rpc_dtablesize;
+    _seterr_reply;
+    _svcauth_none;
+    _svcauth_short;
+    _svcauth_unix;
+
+    # a*
+    authdes_create;
+    authdes_seccreate;
+    authnone_create;
+    authunix_create;
+    authunix_create_default;
+
+    # b*
+    bindresvport;
+    bindresvport_sa;
+
+    # c*
+    callrpc;
+    clnt_broadcast;
+    clnt_create;
+    clnt_create_timed;
+    clnt_create_vers;
+    clnt_create_vers_timed;
+    clnt_dg_create;
+    clnt_pcreateerror;
+    clnt_perrno;
+    clnt_perror;
+    clnt_raw_create;
+    clnt_spcreateerror;
+    clnt_sperrno;
+    clnt_sperror;
+    clnt_tli_create;
+    clnt_tp_create;
+    clnt_tp_create_timed;
+    clnt_vc_create;
+    clntraw_create;
+    clnttcp_create;
+    clntudp_bufcreate;
+    clntudp_create;
+    clntunix_create;
+
+    # e*
+    endnetconfig;
+    endnetpath;
+
+    # f*
+    freenetconfigent;
+
+    # g*
+    get_myaddress;
+    getnetconfig;
+    getnetconfigent;
+    getnetpath;
+    getrpcport;
+
+    # n*
+    nc_perror;
+    nc_sperror;
+
+    # p*
+    pmap_getmaps;
+    pmap_getport;
+    pmap_rmtcall;
+    pmap_set;
+    pmap_unset;
+
+    # r*
+    registerrpc;
+    rpc_broadcast;
+    rpc_broadcast_exp;
+    rpc_call;
+    rpc_control;
+    rpc_createerr;
+    rpc_nullproc;
+    rpc_reg;
+    rpcb_getaddr;
+    rpcb_getmaps;
+    rpcb_gettime;
+    rpcb_rmtcall;
+    rpcb_set;
+    rpcb_taddr2uaddr;
+    rpcb_uaddr2taddr;
+    rpcb_unset;
+
+    # s*
+    setnetconfig;
+    setnetpath;
+    svc_auth_reg;
+    svc_create;
+    svc_dg_create;
+    svc_dg_enablecache;
+    svc_exit;
+    svc_fd_create;
+    svc_fdset;
+    svc_getreq;
+    svc_getreq_common;
+    svc_getreq_poll;
+    svc_getreqset;
+    svc_maxfd;
+    svc_raw_create;
+    svc_reg;
+    svc_register;
+    svc_run;
+    svc_sendreply;
+    svc_tli_create;
+    svc_tp_create;
+    svc_unreg;
+    svc_unregister;
+    svc_vc_create;
+    svcerr_auth;
+    svcerr_decode;
+    svcerr_noproc;
+    svcerr_noprog;
+    svcerr_progvers;
+    svcerr_systemerr;
+    svcerr_weakauth;
+    svcfd_create;
+    svcraw_create;
+    svctcp_create;
+    svcudp_bufcreate;
+    svcudp_create;
+    svcunix_create;
+    svcunixfd_create;
+
+    # t*
+    taddr2uaddr;
+
+    # u*
+    uaddr2taddr;
+
+    # x*
+    xdr_accepted_reply;
+    xdr_array;
+    xdr_authunix_parms;
+    xdr_bool;
+    xdr_bytes;
+    xdr_callhdr; xdr_callmsg;
+    xdr_char;
+    xdr_des_block;
+    xdr_double;
+    xdr_enum;
+    xdr_float;
+    xdr_free;
+    xdr_hyper;
+    xdr_int16_t;
+    xdr_int32_t;
+    xdr_int64_t;
+    xdr_int8_t;
+    xdr_int;
+    xdr_long;
+    xdr_longlong_t;
+    xdr_netbuf;
+    xdr_netobj;
+    xdr_opaque;
+    xdr_opaque_auth;
+    xdr_pmap;
+    xdr_pmaplist;
+    xdr_pmaplist_ptr;
+    xdr_pointer;
+    xdr_quad_t;
+    xdr_reference;
+    xdr_rejected_reply;
+    xdr_replymsg;
+    xdr_rmtcall_args;
+    xdr_rmtcallres;
+    xdr_rpcb;
+    xdr_rpcb_entry;
+    xdr_rpcb_entry_list_ptr;
+    xdr_rpcb_rmtcallargs;
+    xdr_rpcb_rmtcallres;
+    xdr_rpcb_stat;
+    xdr_rpcb_stat_byvers;
+    xdr_rpcblist;
+    xdr_rpcblist_ptr;
+    xdr_rpcbs_addrlist;
+    xdr_rpcbs_addrlist_ptr;
+    xdr_rpcbs_proc;
+    xdr_rpcbs_rmtcalllist;
+    xdr_rpcbs_rmtcalllist_ptr;
+    xdr_short;
+    xdr_string;
+    xdr_u_char;
+    xdr_u_hyper;
+    xdr_u_int16_t;
+    xdr_u_int32_t;
+    xdr_u_int64_t;
+    xdr_u_int8_t;
+    xdr_u_int;
+    xdr_u_long;
+    xdr_u_longlong_t;
+    xdr_u_quad_t;
+    xdr_u_short;
+    xdr_uint16_t;
+    xdr_uint32_t;
+    xdr_uint64_t;
+    xdr_uint8_t;
+    xdr_union;
+    xdr_vector;
+    xdr_void;
+    xdr_wrapstring;
+    xdrmem_create;
+    xdrrec_create;
+    xdrrec_endofrecord;
+    xdrrec_eof;
+    xdrrec_skiprecord;
+    xdrstdio_create;
+    xprt_register;
+    xprt_unregister;
+    # GSS-API symbols (conditionally included)
+@GSS_SYMBOLS@
+    # DES crypto symbols (conditionally included)
+@DES_SYMBOLS@
+    # RPC database symbols (conditionally included)
+@RPCDB_SYMBOLS@
+
+  local:
+    *;
+};
+
+TIRPC_0.3.1 {
+# GSS-API symbols (conditionally included)
+@GSS_SYMBOLS_031@
+} TIRPC_0.3.0;
+
+TIRPC_0.3.2 {
+    getnetname;
+    getpublicandprivatekey;
+    getpublickey;
+    host2netname;
+    key_decryptsession;
+    key_decryptsession_pk;
+    key_encryptsession;
+    key_encryptsession_pk;
+    key_gendes;
+    key_get_conv;
+    key_setsecret;
+    key_secretkey_is_set;
+    key_setnet;
+    netname2host;
+    netname2user;
+    rtime;
+    user2netname;
+    xdr_cryptkeyarg;
+    xdr_cryptkeyarg2;
+    xdr_cryptkeyres;
+    xdr_getcredres;
+    xdr_key_netstarg;
+    xdr_key_netstres;
+    xdr_keybuf;
+    xdr_keystatus;
+    xdr_netnamestr;
+    xdr_unixcred;
+} TIRPC_0.3.1;
+
+TIRPC_0.3.3 {
+    __getpublickey_LOCAL;
+    __key_decryptsession_pk_LOCAL;
+    __key_encryptsession_pk_LOCAL;
+    __key_gendes_LOCAL;
+    xdr_sizeof;
+    authdes_pk_create;
+    svc_pollfd;
+    svc_max_pollfd;
+} TIRPC_0.3.2;
+
+TIRPC_PRIVATE {
+  global:
+    __libc_clntudp_bufcreate;
+  # private, but used by rpcbind:
+    __svc_clean_idle; svc_auth_none; libtirpc_set_debug;
+};
