From 571aac176e94dc669c677041c0bcac7dedcd8067 Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Thu, 16 Sep 2010 12:48:41 +0100 Subject: [PATCH] rx: Add an opaque type Add a type to RX to hold counted data chunks, and some helper functions to assist callers with using that type. Change-Id: Ia81ceea50e43f6fba101122a085f84776dbf3807 Reviewed-on: http://gerrit.openafs.org/2826 Tested-by: BuildBot Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/libafs/Makefile.common.in | 4 + src/libafsrpc/Makefile.in | 4 + src/libafsrpc/NTMakefile | 10 +- src/libuafs/Makefile.common.in | 10 ++ src/rx/Makefile.in | 10 +- src/rx/NTMakefile | 10 +- src/rx/rx_opaque.c | 192 +++++++++++++++++++++++++++++++++ src/rx/rx_opaque.h | 44 ++++++++ src/shlibafsrpc/Makefile.in | 4 + src/shlibafsrpc/libafsrpc.map | 8 ++ 10 files changed, 288 insertions(+), 8 deletions(-) create mode 100644 src/rx/rx_opaque.c create mode 100644 src/rx/rx_opaque.h diff --git a/src/libafs/Makefile.common.in b/src/libafs/Makefile.common.in index b35934c90..9c6b265d6 100644 --- a/src/libafs/Makefile.common.in +++ b/src/libafs/Makefile.common.in @@ -147,6 +147,7 @@ AFSAOBJS = \ rx_kcommon.o \ rx_misc.o \ rx_null.o \ + rx_opaque.o \ rx_getaddr.o \ rx_packet.o \ rx_multi.o \ @@ -216,6 +217,7 @@ AFSPAGOBJS = \ rx_kcommon.o \ rx_misc.o \ rx_null.o \ + rx_opaque.o \ rx_getaddr.o \ rx_packet.o \ rx_multi.o \ @@ -402,6 +404,8 @@ rx_multi.o: $(TOP_SRC_RX)/rx_multi.c $(CRULE_NOOPT) rx_null.o: $(TOP_SRC_RX)/rx_null.c $(CRULE_NOOPT) +rx_opaque.o: $(TOP_SRC_RX)/rx_opaque.c + $(CRULE_OPT) rx_getaddr.o: $(TOP_SRC_RX)/rx_getaddr.c $(CRULE_NOOPT) rx_packet.o: $(TOP_SRC_RX)/rx_packet.c diff --git a/src/libafsrpc/Makefile.in b/src/libafsrpc/Makefile.in index f7a6fe89f..523170203 100644 --- a/src/libafsrpc/Makefile.in +++ b/src/libafsrpc/Makefile.in @@ -67,6 +67,7 @@ RXOBJS =\ rx_pthread.o \ rx.o \ rx_null.o \ + rx_opaque.o \ rx_conncache.o \ rx_globals.o \ rx_getaddr.o \ @@ -167,6 +168,9 @@ rx_conncache.o: ${RX}/rx_conncache.c rx_null.o: ${RX}/rx_null.c ${CCRULE} ${RX}/rx_null.c +rx_opaque.o: ${RX}/rx_opaque.c + ${CCRULE} ${RX}/rx_opaque.c + rx_globals.o: ${RX}/rx_globals.c ${CCRULE} ${RX}/rx_globals.c diff --git a/src/libafsrpc/NTMakefile b/src/libafsrpc/NTMakefile index 3c1ae3f03..31988fe93 100644 --- a/src/libafsrpc/NTMakefile +++ b/src/libafsrpc/NTMakefile @@ -32,9 +32,11 @@ XDROBJS = $(OUT)\xdr.obj $(OUT)\xdr_array.obj $(OUT)\xdr_arrayn.obj $(OUT)\xdr_f $(OUT)\xdr_rec.obj $(OUT)\xdr_refernce.obj $(OUT)\xdr_rx.obj $(OUT)\xdr_update.obj \ $(OUT)\xdr_afsuuid.obj $(OUT)\xdr_int64.obj $(OUT)\xdr_int32.obj $(OUT)\xdr_len.obj -RXOBJS = $(OUT)\rx_event.obj $(OUT)\rx_user.obj $(OUT)\rx_pthread.obj $(OUT)\rx.obj $(OUT)\rx_clock_nt.obj \ - $(OUT)\rx_null.obj $(OUT)\rx_globals.obj $(OUT)\rx_getaddr.obj $(OUT)\rx_misc.obj $(OUT)\rx_packet.obj \ - $(OUT)\rx_rdwr.obj $(OUT)\rx_trace.obj $(OUT)\rx_xmit_nt.obj $(OUT)\rx_conncache.obj +RXOBJS = $(OUT)\rx_event.obj $(OUT)\rx_user.obj $(OUT)\rx_pthread.obj \ + $(OUT)\rx.obj $(OUT)\rx_clock_nt.obj $(OUT)\rx_null.obj \ + $(OUT)\rx_globals.obj $(OUT)\rx_getaddr.obj $(OUT)\rx_misc.obj \ + $(OUT)\rx_packet.obj $(OUT)\rx_rdwr.obj $(OUT)\rx_trace.obj \ + $(OUT)\rx_xmit_nt.obj $(OUT)\rx_conncache.obj $(OUT)\rx_opaque.obj RXSTATBJS = $(OUT)\rxstat.obj $(OUT)\rxstat.ss.obj $(OUT)\rxstat.xdr.obj $(OUT)\rxstat.cs.obj @@ -134,4 +136,4 @@ libstub: $(DESTDIR)\lib\afsrpc.exp clean:: - $(DEL) $(DESTDIR)\lib\afsrpc.dll $(DESTDIR)\lib\afsrpc.lib $(DESTDIR)\lib\afsrpc.exp \ No newline at end of file + $(DEL) $(DESTDIR)\lib\afsrpc.dll $(DESTDIR)\lib\afsrpc.lib $(DESTDIR)\lib\afsrpc.exp diff --git a/src/libuafs/Makefile.common.in b/src/libuafs/Makefile.common.in index f0b436f78..e4ad3d12b 100644 --- a/src/libuafs/Makefile.common.in +++ b/src/libuafs/Makefile.common.in @@ -167,6 +167,7 @@ UAFSOBJ = \ $(UOBJ)/rx_misc.o \ $(UOBJ)/rx_multi.o \ $(UOBJ)/rx_null.o \ + $(UOBJ)/rx_opaque.o \ $(UOBJ)/rx_getaddr.o \ $(UOBJ)/rx_packet.o \ $(UOBJ)/rx_conncache.o \ @@ -306,6 +307,7 @@ AFSWEBOBJ = \ $(WEBOBJ)/rx_misc.o \ $(WEBOBJ)/rx_multi.o \ $(WEBOBJ)/rx_null.o \ + $(WEBOBJ)/rx_opaque.o \ $(WEBOBJ)/rx_getaddr.o \ $(WEBOBJ)/rx_packet.o \ $(WEBOBJ)/rx_conncache.o \ @@ -441,6 +443,7 @@ AFSWEBOBJKRB = \ $(WEBOBJ)/rx_misc.o \ $(WEBOBJ)/rx_multi.o \ $(WEBOBJ)/rx_null.o \ + $(WEBOBJ)/rx_opaque.o \ $(WEBOBJ)/rx_getaddr.o \ $(WEBOBJ)/rx_packet.o \ $(WEBOBJ)/rx_conncache.o \ @@ -578,6 +581,7 @@ JUAFSOBJ = \ $(JUAFS)/rx_misc.o \ $(JUAFS)/rx_multi.o \ $(JUAFS)/rx_null.o \ + $(JUAFS)/rx_opaque.o \ $(JUAFS)/rx_getaddr.o \ $(JUAFS)/rx_packet.o \ $(JUAFS)/rx_conncache.o \ @@ -771,6 +775,8 @@ $(UOBJ)/rx_multi.o: $(TOP_SRC_RX)/rx_multi.c $(CRULE1) $(UOBJ)/rx_null.o: $(TOP_SRC_RX)/rx_null.c $(CRULE1) +$(UOBJ)/rx_opaque.o: $(TOP_SRC_RX)/rx_opaque.c + $(CRULE1) $(UOBJ)/rx_getaddr.o: $(TOP_SRC_RX)/rx_getaddr.c $(CRULE1) $(UOBJ)/rx_packet.o: $(TOP_SRC_RX)/rx_packet.c @@ -1056,6 +1062,8 @@ $(WEBOBJ)/rx_multi.o: $(TOP_SRC_RX)/rx_multi.c $(CRULE2) $(WEBOBJ)/rx_null.o: $(TOP_SRC_RX)/rx_null.c $(CRULE2) +$(WEBOBJ)/rx_opaque.o: $(TOP_SRC_RX)/rx_opaque.c + $(CRULE2) $(WEBOBJ)/rx_getaddr.o: $(TOP_SRC_RX)/rx_getaddr.c $(CRULE2) $(WEBOBJ)/rx_packet.o: $(TOP_SRC_RX)/rx_packet.c @@ -1345,6 +1353,8 @@ $(JUAFS)/rx_multi.o: $(TOP_SRC_RX)/rx_multi.c $(CRULE1) $(JUAFS)/rx_null.o: $(TOP_SRC_RX)/rx_null.c $(CRULE1) +$(JUAFS)/rx_opaque.o: $(TOP_SRC_RX)/rx_opaque.c + $(CRULE1) $(JUAFS)/rx_getaddr.o: $(TOP_SRC_RX)/rx_getaddr.c $(CRULE1) $(JUAFS)/rx_packet.o: $(TOP_SRC_RX)/rx_packet.c diff --git a/src/rx/Makefile.in b/src/rx/Makefile.in index 9cd852ef9..0994b2c71 100644 --- a/src/rx/Makefile.in +++ b/src/rx/Makefile.in @@ -24,7 +24,8 @@ XDROBJS = xdr_arrayn.o ${XDROBJS_common} RXOBJS_common = rx_clock.o rx_event.o rx_user.o rx_lwp.o rx.o rx_null.o \ rx_globals.o rx_getaddr.o rx_misc.o rx_packet.o rx_rdwr.o rx_trace.o \ - rx_conncache.o xdr_int32.o xdr_int64.o xdr_update.o xdr_refernce.o + rx_conncache.o rx_opaque.o \ + xdr_int32.o xdr_int64.o xdr_update.o xdr_refernce.o RXOBJS = ${RXOBJS_common} @@ -97,6 +98,7 @@ includes: \ ${TOP_INCDIR}/rx/rx_lwp.h \ ${TOP_INCDIR}/rx/rx_misc.h \ ${TOP_INCDIR}/rx/rx_null.h \ + ${TOP_INCDIR}/rx/rx_opaque.h \ ${TOP_INCDIR}/rx/xdr.h \ ${TOP_INCDIR}/rx/xdr_prototypes.h @@ -142,6 +144,9 @@ ${TOP_INCDIR}/rx/rx_misc.h: rx_misc.h ${TOP_INCDIR}/rx/rx_null.h: rx_null.h ${INSTALL_DATA} $? $@ +${TOP_INCDIR}/rx/rx_opaque.h: rx_opaque.h + ${INSTALL_DATA} $? $@ + ${TOP_INCDIR}/rx/xdr.h: xdr.h ${INSTALL_DATA} $? $@ @@ -168,6 +173,8 @@ install: librx.a ${INSTALL_DATA} ${srcdir}/rx_lwp.h ${DESTDIR}${includedir}/rx/rx_lwp.h ${INSTALL_DATA} ${srcdir}/rx_misc.h ${DESTDIR}${includedir}/rx/rx_misc.h ${INSTALL_DATA} ${srcdir}/rx_null.h ${DESTDIR}${includedir}/rx/rx_null.h + ${INSTALL_DATA} ${srcdir}/rx_opaque.h \ + ${DESTDIR}${includedir}/rx/rx_opaque.h ${INSTALL_DATA} ${srcdir}/xdr.h ${DESTDIR}${includedir}/rx/xdr.h ${INSTALL_DATA} ${srcdir}/xdr_prototypes.h ${DESTDIR}${includedir}/rx/xdr_prototypes.h @@ -188,6 +195,7 @@ dest: librx.a ${INSTALL_DATA} ${srcdir}/rx_lwp.h ${DEST}/include/rx/rx_lwp.h ${INSTALL_DATA} ${srcdir}/rx_misc.h ${DEST}/include/rx/rx_misc.h ${INSTALL_DATA} ${srcdir}/rx_null.h ${DEST}/include/rx/rx_null.h + ${INSTALL_DATA} ${srcdir}/rx_opaque.h ${DEST}/include/rx/rx_opaque.h ${INSTALL_DATA} ${srcdir}/xdr.h ${DEST}/include/rx/xdr.h ${INSTALL_DATA} ${srcdir}/xdr_prototypes.h ${DEST}/include/rx/xdr_prototypes.h diff --git a/src/rx/NTMakefile b/src/rx/NTMakefile index e40c2841d..67e4b6e40 100644 --- a/src/rx/NTMakefile +++ b/src/rx/NTMakefile @@ -30,9 +30,12 @@ XDROBJS = $(OUT)\xdr.obj $(OUT)\xdr_array.obj $(OUT)\xdr_arrayn.obj $(OUT)\xdr_f $(OUT)\xdr_rec.obj $(OUT)\xdr_refernce.obj $(OUT)\xdr_rx.obj $(OUT)\xdr_update.obj \ $(OUT)\xdr_afsuuid.obj $(OUT)\xdr_int64.obj $(OUT)\xdr_int32.obj $(OUT)\xdr_len.obj -RXOBJS = $(OUT)\rx_event.obj $(OUT)\rx_clock_nt.obj $(OUT)\rx_user.obj $(OUT)\rx_lwp.obj $(OUT)\rx.obj \ - $(OUT)\rx_null.obj $(OUT)\rx_globals.obj $(OUT)\rx_getaddr.obj $(OUT)\rx_misc.obj $(OUT)\rx_packet.obj \ - $(OUT)\rx_rdwr.obj $(OUT)\rx_trace.obj $(OUT)\rx_xmit_nt.obj $(OUT)\rx_conncache.obj +RXOBJS = $(OUT)\rx_event.obj $(OUT)\rx_clock_nt.obj $(OUT)\rx_user.obj \ + $(OUT)\rx_lwp.obj $(OUT)\rx.obj $(OUT)\rx_null.obj \ + $(OUT)\rx_globals.obj $(OUT)\rx_getaddr.obj $(OUT)\rx_misc.obj \ + $(OUT)\rx_packet.obj $(OUT)\rx_rdwr.obj $(OUT)\rx_trace.obj \ + $(OUT)\rx_xmit_nt.obj $(OUT)\rx_conncache.obj \ + $(OUT)\rx_opaque.obj MULTIOBJS = $(OUT)\rx_multi.obj @@ -52,6 +55,7 @@ INCFILES = \ $(INCFILEDIR)\rx_multi.h \ $(INCFILEDIR)\rx_null.h \ $(INCFILEDIR)\rx_lwp.h \ + $(INCFILEDIR)\rx_opaque.h \ $(INCFILEDIR)\rx_pthread.h \ $(INCFILEDIR)\rx_xmit_nt.h \ $(INCFILEDIR)\xdr_prototypes.h \ diff --git a/src/rx/rx_opaque.c b/src/rx/rx_opaque.c new file mode 100644 index 000000000..54c3da80a --- /dev/null +++ b/src/rx/rx_opaque.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2010 Your File System Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#ifndef KERNEL +# include +# include +# include +#else +# include "afs/sysincludes.h" +# include "afsincludes.h" +#endif + +#include +#include + + +/*! + * Generate a new opaque object + * + * Allocate a new opaque object, and copy datalen bytes from data into it. + * The caller should dispose of the resulting object using rx_opaque_free or + * rx_opaque_zeroFree. + * + * @param data + * A pointer to the data to copy into the object + * @param datalen + * The number of bytes of data to copy + * @returns + * A pointer to the allocated opaque object. + */ + +struct rx_opaque * +rx_opaque_new(void *data, size_t datalen) +{ + struct rx_opaque *opaque = rxi_Alloc(sizeof(struct rx_opaque)); + if (opaque != NULL) + rx_opaque_populate(opaque, data, datalen); + return opaque; +} + +/*! + * Allocate space within an existing opaque object + * + * Allocate length bytes of data within an existing opaque object. This will + * overwrite (without freeing) any data that is already held within the + * object. + * + * @param buf + * The opaque object + * @param length + * The number of bytes to allocate + * @returns + * 0 on success, ENOMEM if the memory cannot be allocated. + */ + +int +rx_opaque_alloc(struct rx_opaque *buf, size_t length) +{ + void *mem = rxi_Alloc(length); + if (mem == NULL) + return ENOMEM; + buf->val = mem; + buf->len = length; + memset(buf->val, 0, buf->len); + + return 0; +} + +/*! + * Populate an existing opaque object + * + * Copy datalen bytes from data into an existing opaque object. This allocates + * new data space within the object, and will replace (without freeing) any + * data that is already held within the object. + * + * @param to + * The opaque object to populate + * @param length + * The number of bytes to allocate + * @returns + * 0 on sucess, ENOMEM if memory cannot be allocated + */ + +int +rx_opaque_populate(struct rx_opaque *to, void *data, size_t datalen) +{ + int code; + to->len = 0; + to->val = NULL; + + code = rx_opaque_alloc(to, datalen); + if (code) + return code; + memcpy(to->val, data, datalen); + return 0; +} + +/*! + * Copy data from one opaque object to another + * + * Make a copy of the data held within one existing opaque object into + * another. This allocates new data space within the destination object, + * and will replace (without freeing) any data that is already held within + * this object. + * + * @param to + * To object to copy to + * @param from + * The object to copy data from + * @returns + * 0 on success, ENOMEM if memory cannot be allocated + */ + +int +rx_opaque_copy(struct rx_opaque *to, const struct rx_opaque *from) +{ + return rx_opaque_populate(to, from->val, from->len); +} + +/*! + * Free the contents of an opaque object + * + */ +void +rx_opaque_freeContents(struct rx_opaque *buf) { + if (buf->val) { + rxi_Free(buf->val, buf->len); + } + buf->len = 0; + buf->val = NULL; +} + +/*! + * Zero, then free, the contents of an opaque object + */ +void +rx_opaque_zeroFreeContents(struct rx_opaque *buf) { + if (buf->val) + memset(buf->val, 0, buf->len); + rx_opaque_freeContents(buf); +} + +/*! + * Free an opaque object + * + * This frees the contents of the object, then frees the object itself + */ + +void +rx_opaque_free(struct rx_opaque **buf) { + rx_opaque_freeContents(*buf); + rxi_Free(*buf, sizeof(struct rx_opaque)); + *buf = NULL; +} + +/*! + * Zero, then free an opaque object + * + * This zeros the contents of an opaque object, frees those contents, + * then frees the object itself. + */ + +void +rx_opaque_zeroFree(struct rx_opaque **buf) { + rx_opaque_zeroFreeContents(*buf); + rxi_Free(*buf, sizeof(struct rx_opaque)); + *buf = NULL; +} diff --git a/src/rx/rx_opaque.h b/src/rx/rx_opaque.h new file mode 100644 index 000000000..4dadea35e --- /dev/null +++ b/src/rx/rx_opaque.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010 Your File System Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef OPENAFS_RX_OPAQUE_H +#define OPENAFS_RX_OPAQUE_H + +struct rx_opaque { + size_t len; + void *val; +}; + +#define RX_EMPTY_OPAQUE {0, NULL} + +struct rx_opaque *rx_opaque_new(void *data, size_t datalen); +int rx_opaque_alloc(struct rx_opaque *buf, size_t length); +int rx_opaque_populate(struct rx_opaque *to, void *data, size_t datalen); +int rx_opaque_copy(struct rx_opaque *to, const struct rx_opaque *from); +void rx_opaque_freeContents(struct rx_opaque *buf); +void rx_opaque_zeroFreeContents(struct rx_opaque *buf); +void rx_opaque_free(struct rx_opaque **buf); +void rx_opaque_zeroFree(struct rx_opaque **buf); + +#endif diff --git a/src/shlibafsrpc/Makefile.in b/src/shlibafsrpc/Makefile.in index cebaf9f1c..c0f48faaf 100644 --- a/src/shlibafsrpc/Makefile.in +++ b/src/shlibafsrpc/Makefile.in @@ -71,6 +71,7 @@ RXOBJS =\ rx_pthread.o \ rx.o \ rx_null.o \ + rx_opaque.o \ rx_conncache.o \ rx_globals.o \ rx_getaddr.o \ @@ -187,6 +188,9 @@ rx_conncache.o: ${RX}/rx_conncache.c rx_null.o: ${RX}/rx_null.c ${CCRULE} +rx_opaque.o: ${RX}/rx_opaque.c + ${CCRULE} + rx_globals.o: ${RX}/rx_globals.c ${CCRULE} diff --git a/src/shlibafsrpc/libafsrpc.map b/src/shlibafsrpc/libafsrpc.map index 25eb27b4b..9cbff77cf 100755 --- a/src/shlibafsrpc/libafsrpc.map +++ b/src/shlibafsrpc/libafsrpc.map @@ -150,6 +150,14 @@ rxi_AllocDataBuf; rx_MyMaxSendSize; rxi_Free; + rx_opaque_new; + rx_opaque_alloc; + rx_opaque_populate; + rx_opaque_copy; + rx_opaque_freeContents; + rx_opaque_zeroFreeContents; + rx_opaque_free; + rx_opaque_zeroFree; local: *; }; -- 2.39.5