Hi all,

So I've been thinking about how to reduce the breakage that occasionally
happens to other bits of software on upgrades of libclamav, and I think
I've come up with something that might be of some use.  libtool lets you
use a version script to (on platforms that support it) hide symbols from
being globally visible and version those that are.

The benefits of using this sort of approach is that other applications
that try to use libclamav internal functions will fail to link instead
of just throwing a compiler warning about an implicit function
definition.  This will allow the clamav team to make their public API
more stable, since it is the only thing other people will be using.

The downfall, as I have just found out by setting up a version script,
is the the clamav applications fail to link without exporting quite a
few symbols that really shouldn't be exported by the library.  It also
doesn't actually help with API/ABI changing modifications in the public
API itself - it just frees you to spend more time making sure that can
be left alone while you modify the private functions to your heart's
content.

This says to me that probably the architecture for some of this shared
code is wrong at the moment.  One of the following solutions is probably
useful, but I'll leave it up to you all as to which one you prefer.

1) these symbols should be useable by all applications linking to
libclamav (and they should be cl_ instead of their current naming
scheme).

2) These symbols should not be in libclamav at all.  They should be code
in shared/ which gets turned into a convenience library and linked to
all the applications and the library at build time, presumably
statically.

3) These symbols should be in a second shared library built from shared/
or elsewhere that is installed on the target system.  To discourage use
of this private library, it could be installed in a sub directory of
$libdir, and an rpath added to all the binaries and libclamav.

My personal preference is 2.  It incurs some on disk and memory
overhead, as these symbols will be loaded once for each application,
rather than the normal shared library memory saving techniques.  That
being said, it is the simplest to manage, and is the most effective at
making sure other applications do not link to private functions within
the clamav suite that change between releases.

Ok, so long preamble over.

version script:
CLAMAV_0.92 {
  global:
    cl_*;
    cli_calloc;
    cli_chomp;
    cli_dbgmsg;
    cli_errmsg;
    cli_gentemp;
    cli_gentempdesc;
    cli_leavetemps_flag;
    cli_malloc;
    cli_md5file;
    cli_md5stream;
    cli_memstr;
    cli_ole2_extract;
    cli_readn;
    cli_realloc;
    cli_rmdirs;
    cli_rndnum;
    cli_str2hex;
    cli_strbcasestr;
    cli_strdup;
    cli_strrcpy;
    cli_strtok;
    cli_strtokbuf;
    cli_unlockdb;
    cli_untgz;
    cli_utf16toascii;
    cli_versigpss;
    cli_warnmsg;
    cli_writelockdb;
    html_normalise_fd;
    ppt_vba_read;
    sha256_digest;
    sha256_final;
    sha256_init;
    sha256_update;
    tableCreate;
    tableDestroy;
    tableFind;
    tableInsert;
    tableIterate;
    tableRemove;
    tableUpdate;
    vba56_dir_read;
    vba_decompress;
    wm_decrypt_macro;
    wm_dir_read;
  local:
    *;
};

Everything in global: is exported and useable at link time.  Everything
in local is not.  As you can see, you can use wildcards, and you can
also chain versions, so that if a symbol is introduced or removed in a
later version of the library, it gets versioned correctly.  All very
nice stuff.

The automake patches:
Index: libclamav/Makefile.am
===================================================================
--- libclamav/Makefile.am       (revision 572)
+++ libclamav/Makefile.am       (working copy)
@@ -21,8 +21,10 @@
 
 libclamav_la_LIBADD = @LIBCLAMAV_LIBS@ @THREAD_LIBS@
 
-libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ 
-no-undefined
+libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ 
-no-undefined -Wl,[EMAIL PROTECTED]@/libclamav/libclamav.map
 
+EXTRA_DIST = libclamav.map
+
 include_HEADERS = clamav.h
 
 libclamav_la_SOURCES = \
Index: libclamav/Makefile.in
===================================================================
--- libclamav/Makefile.in       (revision 572)
+++ libclamav/Makefile.in       (working copy)
@@ -238,7 +238,8 @@
 target_vendor = @target_vendor@
 INCLUDES = -I$(top_srcdir) [EMAIL PROTECTED]@/unrar [EMAIL PROTECTED]@/nsis
 libclamav_la_LIBADD = @LIBCLAMAV_LIBS@ @THREAD_LIBS@
-libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ 
-no-undefined
+libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ 
-no-undefined -Wl,[EMAIL PROTECTED]@/libclamav/libclamav.map
+EXTRA_DIST = libclamav.map
 include_HEADERS = clamav.h
 libclamav_la_SOURCES = \
        clamav.h \

That's about it.  This is against current stable, although rerevving it
against svn would be fairly trivial.

Is this something people are interested in?  If so, how can I help to
get the list down to 

  global:
    cl_*;
  local:
    *;

?

Happy hacking,
-- 
 --------------------------------------------------------------------------
|  Stephen Gran                  | <Joy> that's a Kludge(TM) <knghtbrd> It |
|  [EMAIL PROTECTED]             | Works(tm) <Joy> AIX works(TM)           |
|  http://www.lobefin.net/~steve | <knghtbrd> no it doesn't <knghtbrd> =>  |
 --------------------------------------------------------------------------

Attachment: signature.asc
Description: Digital signature

_______________________________________________
http://lurker.clamav.net/list/clamav-devel.html
Please submit your patches to our Bugzilla: http://bugs.clamav.net

Reply via email to