From b94e66c48605640cf3ab49e58217b14fa9e28eb2 Mon Sep 17 00:00:00 2001 From: aCaB Date: Fri, 17 Oct 2008 17:00:13 +0000 Subject: [PATCH 02/21] HIGLY EXPERIMENTAL memory pool for libclamav The goal is to put an end to memory wasted due to stupid allocators and fragmentation In the long run mpool libraries will be replaced with better code. For now there just good enough. This branch is currently under development and totally broken. If it will ever compile, it'll probably result in random crashes or at least (slightly) higher load times. The code is also terrible, just don't look. Do not use except for testing. git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4266 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/clamav.h | 8 + libclamav/dconf.c | 13 +- libclamav/dconf.h | 8 + libclamav/matcher-ac.c | 185 ++- libclamav/matcher-bm.c | 13 +- libclamav/matcher.h | 6 + libclamav/mpool-2.1.0/ChangeLog.1 | 86 ++ libclamav/mpool-2.1.0/Makefile | 56 + libclamav/mpool-2.1.0/NEWS | 11 + libclamav/mpool-2.1.0/README | 46 + libclamav/mpool-2.1.0/mpool.c | 1734 +++++++++++++++++++++++++++++ libclamav/mpool-2.1.0/mpool.h | 462 ++++++++ libclamav/mpool-2.1.0/mpool_loc.h | 116 ++ libclamav/mpool-2.1.0/mpool_t.c | 914 +++++++++++++++ libclamav/phishcheck.c | 12 + libclamav/readdb.c | 22 + 16 files changed, 3686 insertions(+), 6 deletions(-) create mode 100644 libclamav/mpool-2.1.0/ChangeLog.1 create mode 100644 libclamav/mpool-2.1.0/Makefile create mode 100644 libclamav/mpool-2.1.0/NEWS create mode 100644 libclamav/mpool-2.1.0/README create mode 100644 libclamav/mpool-2.1.0/mpool.c create mode 100644 libclamav/mpool-2.1.0/mpool.h create mode 100644 libclamav/mpool-2.1.0/mpool_loc.h create mode 100644 libclamav/mpool-2.1.0/mpool_t.c diff --git a/libclamav/clamav.h b/libclamav/clamav.h index a4b856cf7..ae0ca441e 100644 --- a/libclamav/clamav.h +++ b/libclamav/clamav.h @@ -23,6 +23,10 @@ #include #include + +#ifdef USE_MPOOL +#include mpool.h +#endif #ifdef __cplusplus extern "C" @@ -152,6 +156,10 @@ struct cl_engine { /* PUA categories (to be included or excluded) */ char *pua_cats; + +#ifdef USE_MPOOL + mpool_t *mempool; +#endif }; struct cl_limits { diff --git a/libclamav/dconf.c b/libclamav/dconf.c index 00cf79ca5..ec2bb3095 100644 --- a/libclamav/dconf.c +++ b/libclamav/dconf.c @@ -35,6 +35,10 @@ #include "str.h" #include "others.h" +#ifdef USE_MPOOL +#include "mpool.h" +#endif + struct dconf_module { const char *mname; /* module name */ const char *sname; /* submodule name */ @@ -108,13 +112,20 @@ static struct dconf_module modules[] = { { NULL, NULL, 0, 0 } }; +#ifdef USE_MPOOL +struct cli_dconf *cli_dconf_init(mpool_t mempool) +#else struct cli_dconf *cli_dconf_init(void) +#endif { unsigned int i; struct cli_dconf *dconf; - +#ifdef USE_MPOOL + dconf = (struct cli_dconf *) mpool_calloc(mempool, sizeof(struct cli_dconf), 1, NULL); +#else dconf = (struct cli_dconf *) cli_calloc(sizeof(struct cli_dconf), 1); +#endif if(!dconf) return NULL; diff --git a/libclamav/dconf.h b/libclamav/dconf.h index 28d3a2a32..6e6983de2 100644 --- a/libclamav/dconf.h +++ b/libclamav/dconf.h @@ -29,6 +29,10 @@ #include "cltypes.h" #include "cvd.h" +#ifdef USE_MPOOL +#include "mpool.h" +#endif + struct cli_dconf { uint32_t pe; uint32_t elf; @@ -97,7 +101,11 @@ struct cli_dconf { #define PHISHING_CONF_ENGINE 0x1 #define PHISHING_CONF_ENTCONV 0x2 +#ifdef USE_MPOOL +struct cli_dconf *cli_dconf_init(mpool_t); +#else struct cli_dconf *cli_dconf_init(void); +#endif void cli_dconf_print(struct cli_dconf *dconf); int cli_dconf_load(FILE *fs, struct cl_engine **engine, unsigned int options, struct cli_dbio *dbio); #endif diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c index d79754df4..ff021600d 100644 --- a/libclamav/matcher-ac.c +++ b/libclamav/matcher-ac.c @@ -39,6 +39,10 @@ #include "str.h" #include "readdb.h" +#ifdef USE_MPOOL +#include "mpool.h" +#endif + uint8_t cli_ac_mindepth = AC_DEFAULT_MIN_DEPTH; uint8_t cli_ac_maxdepth = AC_DEFAULT_MAX_DEPTH; @@ -66,7 +70,11 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) for(i = 0; i < len; i++) { if(!pt->trans) { +#ifdef USE_MPOOL + pt->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *), NULL); +#else pt->trans = (struct cli_ac_node **) cli_calloc(256, sizeof(struct cli_ac_node *)); +#endif if(!pt->trans) { cli_errmsg("cli_ac_addpatt: Can't allocate memory for pt->trans\n"); return CL_EMEM; @@ -76,17 +84,29 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) next = pt->trans[(unsigned char) (pattern->pattern[i] & 0xff)]; if(!next) { +#ifdef USE_MPOOL + next = (struct cli_ac_node *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_node), NULL); +#else next = (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node)); +#endif if(!next) { cli_errmsg("cli_ac_addpatt: Can't allocate memory for AC node\n"); return CL_EMEM; } if(i != len - 1) { +#ifdef USE_MPOOL + next->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *), NULL); +#else next->trans = (struct cli_ac_node **) cli_calloc(256, sizeof(struct cli_ac_node *)); +#endif if(!next->trans) { cli_errmsg("cli_ac_addpatt: Can't allocate memory for next->trans\n"); +#ifdef USE_MPOOL + mpool_free(root->mempool, next); +#else free(next); +#endif return CL_EMEM; } } else { @@ -94,13 +114,22 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) } root->ac_nodes++; +#ifdef USE_MPOOL + newtable = mpool_resize(root->mempool, root->ac_nodetable, root->ac_nodes * sizeof(struct cli_ac_node *), NULL); +#else newtable = cli_realloc(root->ac_nodetable, root->ac_nodes * sizeof(struct cli_ac_node *)); +#endif if(!newtable) { root->ac_nodes--; cli_errmsg("cli_ac_addpatt: Can't realloc ac_nodetable\n"); if(next->trans) +#ifdef USE_MPOOL + mpool_free(root->mempool, next->trans); + mpool_free(root->mempool, next); +#else free(next->trans); free(next); +#endif return CL_EMEM; } root->ac_nodetable = (struct cli_ac_node **) newtable; @@ -114,7 +143,11 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) } root->ac_patterns++; +#ifdef USE_MPOOL + newtable = mpool_resize(root->mempool, root->ac_pattable, root->ac_patterns * sizeof(struct cli_ac_patt *), NULL); +#else newtable = cli_realloc(root->ac_pattable, root->ac_patterns * sizeof(struct cli_ac_patt *)); +#endif if(!newtable) { root->ac_patterns--; cli_errmsg("cli_ac_addpatt: Can't realloc ac_pattable\n"); @@ -299,16 +332,28 @@ int cli_ac_buildtrie(struct cli_matcher *root) int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth) { +#ifdef USE_MPOOL + root->ac_root = (struct cli_ac_node *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_node), NULL); +#else root->ac_root = (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node)); +#endif if(!root->ac_root) { cli_errmsg("cli_ac_init: Can't allocate memory for ac_root\n"); return CL_EMEM; } +#ifdef USE_MPOOL + root->ac_root->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *), NULL); +#else root->ac_root->trans = (struct cli_ac_node **) cli_calloc(256, sizeof(struct cli_ac_node *)); +#endif if(!root->ac_root->trans) { cli_errmsg("cli_ac_init: Can't allocate memory for ac_root->trans\n"); +#ifdef USE_MPOOL + mpool_free(engine->mempool, root->ac_root, sizeof(struct cli_ac_node)); +#else free(root->ac_root); +#endif return CL_EMEM; } @@ -318,7 +363,11 @@ int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth) return CL_SUCCESS; } +#ifdef USE_MPOOL +static void ac_free_alt(mpool_t *mempool, struct cli_ac_patt *p) +#else static void ac_free_alt(struct cli_ac_patt *p) +#endif { uint16_t i; struct cli_ac_alt *a1, *a2; @@ -333,11 +382,20 @@ static void ac_free_alt(struct cli_ac_patt *p) a2 = a1; a1 = a1->next; if(a2->str) +#ifdef USE_MPOOL + mpool_free(mempool, a2->str); + mpool_free(mempool, a2); +#else free(a2->str); free(a2); +#endif } } +#ifdef USE_MPOOL + mpool_free(mempool, p->alttable); +#else free(p->alttable); +#endif } void cli_ac_free(struct cli_matcher *root) @@ -1093,8 +1151,11 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(strlen(hexsig) / 2 < root->ac_mindepth) return CL_EPATSHORT; - +#ifdef USE_MPOOL + if((new = (struct cli_ac_patt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_patt), NULL)) == NULL) +#else if((new = (struct cli_ac_patt *) cli_calloc(1, sizeof(struct cli_ac_patt))) == NULL) +#endif return CL_EMEM; new->rtype = rtype; @@ -1114,7 +1175,11 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(strchr(hexsig, '[')) { if(!(hexcpy = cli_strdup(hexsig))) { +#ifdef USE_MPOOL + mpool_free(root->mempool, new); +#else free(new); +#endif return CL_EMEM; } @@ -1179,14 +1244,22 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(error) { free(hexcpy); +#ifdef USE_MPOOL + mpool_free(root->mempool, new); +#else free(new); +#endif return error; } hex = cli_strdup(hex); free(hexcpy); if(!hex) { +#ifdef USE_MPOOL + mpool_free(root->mempool, new); +#else free(new); +#endif return CL_EMEM; } } @@ -1197,13 +1270,22 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(hex) { hexcpy = hex; } else if(!(hexcpy = cli_strdup(hexsig))) { +#ifdef USE_MPOOL + mpool_free(root->mempool, new); +#else free(new); +#endif return CL_EMEM; } +#ifdef USE_MPOOL + if(!(hexnew = (char *) mpool_calloc(root->mempool, strlen(hexsig) + 1, 1, NULL))) { + mpool_free(root->mempool, new); +#else if(!(hexnew = (char *) cli_calloc(strlen(hexsig) + 1, 1))) { - free(hexcpy); free(new); +#endif + free(hexcpy); return CL_EMEM; } @@ -1225,7 +1307,11 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex } *start++ = 0; +#ifdef USE_MPOOL + newalt = (struct cli_ac_alt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_alt), NULL); +#else newalt = (struct cli_ac_alt *) cli_calloc(1, sizeof(struct cli_ac_alt)); +#endif if(!newalt) { cli_errmsg("cli_ac_addsig: Can't allocate newalt\n"); error = CL_EMEM; @@ -1233,10 +1319,19 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex } new->alt++; + +#ifdef USE_MPOOL + newtable = (struct cli_ac_alt **) mpool_resize(root->mempool, new->alttable, new->alt * sizeof(struct cli_ac_alt *), NULL); +#else newtable = (struct cli_ac_alt **) cli_realloc(new->alttable, new->alt * sizeof(struct cli_ac_alt *)); +#endif if(!newtable) { new->alt--; +#ifdef USE_MPOOL + mpool_free(root->mempool, newalt); +#else free(newalt); +#endif cli_errmsg("cli_ac_addsig: Can't realloc new->alttable\n"); error = CL_EMEM; break; @@ -1256,7 +1351,11 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(3 * newalt->num - 1 == (uint16_t) strlen(pt)) { newalt->chmode = 1; +#ifdef USE_MPOOL + newalt->str = (unsigned char *) mpool_alloc(root->mempool, newalt->num, NULL); +#else newalt->str = (unsigned char *) cli_malloc(newalt->num); +#endif if(!newalt->str) { cli_errmsg("cli_ac_addsig: Can't allocate newalt->str\n"); error = CL_EMEM; @@ -1285,7 +1384,11 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex while(altpt->next) altpt = altpt->next; +#ifdef USE_MPOOL + altpt->next = (struct cli_ac_alt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_alt), NULL); +#else altpt->next = (struct cli_ac_alt *) cli_calloc(1, sizeof(struct cli_ac_alt)); +#endif if(!altpt->next) { cli_errmsg("cli_ac_addsig: Can't allocate altpt->next\n"); error = CL_EMEM; @@ -1318,20 +1421,46 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(error) { if(new->alt) { free(hex); +#ifdef USE_MPOOL + ac_free_alt(root->mempool, new); + } + mpool_free(root->mempool, new); +#else ac_free_alt(new); } free(new); +#endif return error; } } - if((new->pattern = cli_hex2ui(hex ? hex : hexsig)) == NULL) { +#ifdef USE_MPOOL +{ + unsigned int mpoolhexlen = (strlen(hex ? hex : hexsig) / 2 + 1) * sizeof(uint16_t); + uint16_t *mpoolpatt = cli_hex2ui(hex ? hex : hexsig); + if(mpoolpatt) { + if((new->pattern = mpool_alloc(root->mempool, mpoolhexlen, NULL)) != NULL) + memcpy(new->pattern, mpoolpatt, mpoolhexlen); + free(mpoolpatt); + } else new->pattern = NULL; +} +#else + new->pattern = cli_hex2ui(hex ? hex : hexsig) +#endif + + if(new->pattern == NULL) { if(new->alt) +#ifdef USE_MPOOL + ac_free_alt(root->mempool, new); + mpool_free(root->mempool, new); +#else ac_free_alt(new); - free(hex); free(new); +#endif + free(hex); return CL_EMALFDB; } + new->length = strlen(hex ? hex : hexsig) / 2; free(hex); @@ -1375,9 +1504,15 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(plen < root->ac_mindepth) { cli_errmsg("cli_ac_addsig: Can't find a static subpattern of length %u\n", root->ac_mindepth); +#ifdef USE_MPOOL + ac_free_alt(root->mempool, new); + mpool_free(root->mempool, new->pattern); + mpool_free(root->mempool, new); +#else ac_free_alt(new); free(new->pattern); free(new); +#endif return CL_EMALFDB; } @@ -1394,11 +1529,28 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(new->length > root->maxpatlen) root->maxpatlen = new->length; +#ifdef USE_MPOOL +{ + char *mpoolvirname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); + if(mpoolvirname) { + unsigned int mpoolvirnamesz = strlen(mpoolvirname) + 1; + if((new->virname = mpool_alloc(root->mempool, mpoolvirnamesz, NULL)) != NULL) + memcpy(new->virname, mpoolvirname, mpoolvirnamesz); + } else new->virname = NULL; +} +#else new->virname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); +#endif if(!new->virname) { +#ifdef USE_MPOOL + new->prefix ? mpool_free(root->mempool, new->prefix) : mpool_free(root->mempool, new->pattern); + ac_free_alt(root->mempool, new); + mpool_free(root->mempool, new); +#else new->prefix ? free(new->prefix) : free(new->pattern); ac_free_alt(new); free(new); +#endif return CL_EMEM; } @@ -1406,23 +1558,48 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex root->ac_lsigtable[new->lsigid[1]]->virname = new->virname; if(offset) { +#ifdef USE_MPOOL + char *mpooloffset = cli_strdup(offset); + if(mpooloffset) { + unsigned int mpooloffsetsz = strlen(mpooloffset) + 1; + if((new->offset = mpool_alloc(root->mempool, mpooloffsetsz, NULL))) + memcpy(new->offset, mpooloffset, mpooloffsetsz); + } else new->offset = NULL; +#else new->offset = cli_strdup(offset); +#endif if(!new->offset) { +#ifdef USE_MPOOL + new->prefix ? mpool_free(rool->mempool, new->prefix) : mpool_free(root->mempool, new->pattern); + ac_free_alt(root->mempool, new); + mpool_free(root->mempool, new->virname); + mpool_free(root->mempool, new); +#else new->prefix ? free(new->prefix) : free(new->pattern); ac_free_alt(new); free(new->virname); free(new); +#endif return CL_EMEM; } } if((ret = cli_ac_addpatt(root, new))) { +#ifdef USE_MPOOL + new->prefix ? mpool_free(rool->mempool, new->prefix) : mpool_free(root->mempool, new->pattern); + mpool_free(root->mempool, new->virname); + ac_free_alt(root->mempool, new); + if(new->offset) + mpool_free(root->mempool, new->offset); + mpool_free(root->mempool, new); +#else new->prefix ? free(new->prefix) : free(new->pattern); free(new->virname); ac_free_alt(new); if(new->offset) free(new->offset); free(new); +#endif return ret; } diff --git a/libclamav/matcher-bm.c b/libclamav/matcher-bm.c index a3b696a3b..4ac58b191 100644 --- a/libclamav/matcher-bm.c +++ b/libclamav/matcher-bm.c @@ -32,6 +32,10 @@ #include "matcher-bm.h" #include "filetypes.h" +#ifdef USE_MPOOL +#include "mpool.h" +#endif + #define BM_MIN_LENGTH 3 #define BM_BLOCK_SIZE 3 #define HASH(a,b,c) (211 * a + 37 * b + c) @@ -97,12 +101,19 @@ int cli_bm_init(struct cli_matcher *root) { uint16_t i, size = HASH(255, 255, 255) + 1; - +#ifdef USE_MPOOL + if(!(root->bm_shift = (uint8_t *) mpool_calloc(root->mempool, size, sizeof(uint8_t), NULL))) +#else if(!(root->bm_shift = (uint8_t *) cli_calloc(size, sizeof(uint8_t)))) +#endif return CL_EMEM; if(!(root->bm_suffix = (struct cli_bm_patt **) cli_calloc(size, sizeof(struct cli_bm_patt *)))) { +#ifdef USE_MPOOL + mpool_free(root->mempool, root->bm_shift, size * sizeof(uint8_t)); +#else free(root->bm_shift); +#endif return CL_EMEM; } diff --git a/libclamav/matcher.h b/libclamav/matcher.h index 2e28c1e5a..cd7fd69d0 100644 --- a/libclamav/matcher.h +++ b/libclamav/matcher.h @@ -34,6 +34,11 @@ #include "matcher-bm.h" #include "hashtab.h" +#ifdef USE_MPOOL +#include "mpool.h" +#endif + + #define CLI_MATCH_WILDCARD 0xff00 #define CLI_MATCH_CHAR 0x0000 #define CLI_MATCH_IGNORE 0x0100 @@ -80,6 +85,7 @@ struct cli_matcher { uint16_t maxpatlen; uint8_t ac_only; + mpool_t mempool; }; struct cli_meta_node { diff --git a/libclamav/mpool-2.1.0/ChangeLog.1 b/libclamav/mpool-2.1.0/ChangeLog.1 new file mode 100644 index 000000000..40c4a53ee --- /dev/null +++ b/libclamav/mpool-2.1.0/ChangeLog.1 @@ -0,0 +1,86 @@ +2006-05-31 Gray Watson <> + + * Version 2.1.0 released. + + * Added MPOOL_ERROR_PNT_OVER to distinguish between pointer + overwrite and mpool structure overwrite. + +2005-05-20 Gray Watson <> + + * Version 2.0.0 released. + + * First external publication of library. + +Thu Mar 4 10:14:21 1999 Gray Watson <> + + * Reworked the way the blocks were split up. + + * Removed the round arguments. Not used. + +Wed Mar 3 19:29:38 1999 Gray Watson <> + + * Moved to random(). Fucking rand() was hiding a lot of problems + from me. + + * Added some additional sanity checks in free(). + + * Added mpool_set_max_pages to the library. + +Thu Feb 25 12:41:51 1999 Gray Watson <> + + * Added log_function transaction callback. + +Thu Feb 25 09:53:33 1999 Gray Watson <> + + * Changed the default page size to 16 * getpagesize. + +Wed Feb 24 17:52:52 1999 Gray Watson <> + + * Major reworking of internals to simplify structures. + +Fri Feb 19 12:52:55 1999 Gray Watson <> + + * Made a number of changes to the internals which removed the + addr_to_block as a performance pig. + +Tue Feb 16 21:11:23 1999 Gray Watson <> + + * Added ability for free to look up in the free bit lists for + memory to use. + + * Added mpool_clear. Good idea. + +Thu Feb 11 02:53:45 1999 Gray Watson <> + + * Finally a working version. Looks much better. + + * Added rounding sizes so it will allocate aligned memory. + + * Added minimum size to the mpool_free function to speed it up. + +Wed Feb 10 23:30:48 1999 Gray Watson <> + + * Version 1 with new fine grained memory resolution almost + working. + +Fri May 2 02:26:28 1997 Gray Watson <> + + * Moved to MAP_PRIVATE from MAP_SHARED. + + * Fixed the min/max handling. + + * Added additional info to mpool_stat. + +Thu May 1 16:51:06 1997 Gray Watson <> + + * Added page-size information request. + + * Added better no-memory errors. + +Thu Apr 24 01:58:41 1997 Gray Watson <> + + * Added handling of null for debugging purposes. + +Mon Apr 14 03:31:26 1997 Gray Watson <> + + * Started the mpool routines. diff --git a/libclamav/mpool-2.1.0/Makefile b/libclamav/mpool-2.1.0/Makefile new file mode 100644 index 000000000..fd34e311b --- /dev/null +++ b/libclamav/mpool-2.1.0/Makefile @@ -0,0 +1,56 @@ +# +# $Id: Makefile.all,v 1.1.1.1 2005/05/20 19:58:29 gray Exp $ +# + +HFLS = mpool.h +OBJS = mpool.o + +CC = cc + +CFLAGS = -g -I. $(DEFINES) +#CFLAGS = -g -I. +LDFLAGS = +RANLIB = ranlib + +DESTDIR = /usr/local +TEST = mpool_t +LIBRARY = libmpool.a + +all : $(LIBRARY) $(UTIL) + +clean : + rm -f a.out core *.o *.t + rm -f $(LIBRARY) $(TEST) + +install : $(HFLS) $(LIBRARY) + install -c -m 444 $(HFLS) $(DESTDIR)/include + install -c -m 444 $(LIBRARY) $(DESTDIR)/lib + $(RANLIB) $(DESTDIR)/libo/$(LIBRARY) + +$(LIBRARY) : $(OBJS) + ar cr $(LIBRARY) $? + $(RANLIB) $@ + +tests : $(TEST) + +$(TEST) : $(TEST).o $(LIBRARY) + rm -f $@ + $(CC) $(LDFLAGS) $(TEST).o $(LIBRARY) + mv a.out $@ + +$(UTIL) : $(UTIL).o $(LIBRARY) + rm -f $@ + $(CC) $(LDFLAGS) $(UTIL).o $(LIBRARY) + mv a.out $@ + +.c.o : + rm -f $@ + $(CC) $(CFLAGS) -c $< -o $@ + +# +# Below are dependencies that are automatically generated by make +# depend. Please do not edit by hand. +# + +mpool.o: mpool.c mpool.h mpool_loc.h +mpool_t.o: mpool_t.c mpool.h diff --git a/libclamav/mpool-2.1.0/NEWS b/libclamav/mpool-2.1.0/NEWS new file mode 100644 index 000000000..f6c0ab2a1 --- /dev/null +++ b/libclamav/mpool-2.1.0/NEWS @@ -0,0 +1,11 @@ +------------------------------------------------------------------------------- +$Id: NEWS,v 1.2 2006/05/31 20:28:31 gray Exp $ +------------------------------------------------------------------------------- + +Version 2.1.0: + + * Added MPOOL_ERROR_PNT_OVER to show pointer overwrites. + +Version 2.0.0: + + * Initial external release of library after use since 1996. diff --git a/libclamav/mpool-2.1.0/README b/libclamav/mpool-2.1.0/README new file mode 100644 index 000000000..7277ff2ad --- /dev/null +++ b/libclamav/mpool-2.1.0/README @@ -0,0 +1,46 @@ +------------------------------------------------------------------------------- +$Id: README,v 1.2 2005/05/22 19:49:30 gray Exp $ +------------------------------------------------------------------------------- + +BACKGROUND: + +This is a memory pool library which was written to allow a program to +have heaps that it could destroy without fragmenting memory. You can +have multiple heaps and reset them easily completely reclaiming the +memory (as opposed to standard heaps). + +With it you can mpool_open() a new heap, then mpool_alloc(), +mpool_calloc(), mpool_realloc(), mpool_free() to your heart's content. +Once you are done with the memory-pool you can run mpool_clear() or +mpool_close() and completely remove the memory associated with the +pools. This is very handy if you are working with some large blocks +of memory and want to reset back to a clean state. + +Check out the mpool.h file for more information. Sorry for minimal +docs. + +------------------------------------------------------------------------------- + +INSTALLATION: + +1) Typing 'make' should be enough to build libskip.a. +2) Typing 'make tests' should make the mpool_t test program. + +------------------------------------------------------------------------------- + +REPOSITORY: + +The newest versions of the library are available from: + + http://256.com/sources/mpool/ + +------------------------------------------------------------------------------- + +AUTHOR: + +If you have any questions or problems feel free to send me mail. + +Gray Watson +http://256.com/gray/ + +------------------------------------------------------------------------------- diff --git a/libclamav/mpool-2.1.0/mpool.c b/libclamav/mpool-2.1.0/mpool.c new file mode 100644 index 000000000..5e67c5c8e --- /dev/null +++ b/libclamav/mpool-2.1.0/mpool.c @@ -0,0 +1,1734 @@ +/* + * Memory pool routines. + * + * Copyright 1996 by Gray Watson. + * + * This file is part of the mpool package. + * + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies, and that the name of Gray Watson not be used in advertising + * or publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $ + */ + +/* + * Memory-pool allocation routines. I got sick of the GNU mmalloc + * library which was close to what we needed but did not exactly do + * what I wanted. + * + * The following uses mmap from /dev/zero. It allows a number of + * allocations to be made inside of a memory pool then with a clear or + * close the pool can be reset without any memory fragmentation and + * growth problems. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef DMALLOC +#include "dmalloc.h" +#endif + +#define MPOOL_MAIN + +#include "mpool.h" +#include "mpool_loc.h" + +#ifdef __GNUC__ +#ident "$Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $" +#else +static char *rcs_id = "$Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $"; +#endif + +/* ACAB */ +#include +struct FRAG { + unsigned long frag_size; + void *frag_ptr; +}; +#define FRAG_OVERHEAD (offsetof(struct FRAG, frag_ptr)) + +/* version */ +static char *version = "mpool library version 2.1.0"; + +/* local variables */ +static int enabled_b = 0; /* lib initialized? */ +static unsigned int min_bit_free_next = 0; /* min size of next pnt */ +static unsigned int min_bit_free_size = 0; /* min size of next + size */ +static unsigned long bit_array[MAX_BITS + 1]; /* size -> bit */ + +/****************************** local utilities ******************************/ + +/* + * static void startup + * + * DESCRIPTION: + * + * Perform any library level initialization. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * None. + */ +static void startup(void) +{ + int bit_c; + unsigned long size = 1; + + if (enabled_b) { + return; + } + + /* allocate our free bit array list */ + for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { + bit_array[bit_c] = size; + + /* + * Note our minimum number of bits that can store a pointer. This + * is smallest address that we can have a linked list for. + */ + if (min_bit_free_next == 0 && size >= sizeof(void *)) { + min_bit_free_next = bit_c; + } + /* + * Note our minimum number of bits that can store a pointer and + * the size of the block. + */ + if (min_bit_free_size == 0 && size >= sizeof(mpool_free_t)) { + min_bit_free_size = bit_c; + } + + size *= 2; + } + + enabled_b = 1; +} + +/* + * static int size_to_bits + * + * DESCRIPTION: + * + * Calculate the number of bits in a size. + * + * RETURNS: + * + * Number of bits. + * + * ARGUMENTS: + * + * size -> Size of memory of which to calculate the number of bits. + */ +static int size_to_bits(const unsigned long size) +{ + int bit_c = 0; + + for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { + if (size <= bit_array[bit_c]) { + break; + } + } + + return bit_c; +} + +/* + * static int size_to_free_bits + * + * DESCRIPTION: + * + * Calculate the number of bits in a size going on the free list. + * + * RETURNS: + * + * Number of bits. + * + * ARGUMENTS: + * + * size -> Size of memory of which to calculate the number of bits. + */ +static int size_to_free_bits(const unsigned long size) +{ + int bit_c = 0; + + if (size == 0) { + return 0; + } + + for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { + if (size < bit_array[bit_c]) { + break; + } + } + + return bit_c - 1; +} + +/* + * static int bits_to_size + * + * DESCRIPTION: + * + * Calculate the size represented by a number of bits. + * + * RETURNS: + * + * Number of bits. + * + * ARGUMENTS: + * + * bit_n -> Number of bits + */ +static unsigned long bits_to_size(const int bit_n) +{ + if (bit_n > MAX_BITS) { + return bit_array[MAX_BITS]; + } + else { + return bit_array[bit_n]; + } +} + +/* + * static void *alloc_pages + * + * DESCRIPTION: + * + * Allocate space for a number of memory pages in the memory pool. + * + * RETURNS: + * + * Success - New pages of memory + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to our memory pool. + * + * page_n -> Number of pages to alloc. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +static void *alloc_pages(mpool_t *mp_p, const unsigned int page_n, + int *error_p) +{ + void *mem, *fill_mem; + unsigned long size, fill; + int state; + + /* are we over our max-pages? */ + if (mp_p->mp_max_pages > 0 && mp_p->mp_page_c >= mp_p->mp_max_pages) { + SET_POINTER(error_p, MPOOL_ERROR_NO_PAGES); + return NULL; + } + + size = SIZE_OF_PAGES(mp_p, page_n); + +#ifdef DEBUG + (void)printf("allocating %u pages or %lu bytes\n", page_n, size); +#endif + + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) { + mem = sbrk(size); + if (mem == (void *)-1) { + SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); + return NULL; + } + fill = (unsigned long)mem % mp_p->mp_page_size; + + if (fill > 0) { + fill = mp_p->mp_page_size - fill; + fill_mem = sbrk(fill); + if (fill_mem == (void *)-1) { + SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); + return NULL; + } + if ((char *)fill_mem != (char *)mem + size) { + SET_POINTER(error_p, MPOOL_ERROR_SBRK_CONTIG); + return NULL; + } + mem = (char *)mem + fill; + } + } + else { + state = MAP_PRIVATE; +#ifdef MAP_FILE + state |= MAP_FILE; +#endif +#ifdef MAP_VARIABLE + state |= MAP_VARIABLE; +#endif + + /* mmap from /dev/zero */ + mem = mmap((caddr_t)mp_p->mp_addr, size, PROT_READ | PROT_WRITE, state, + mp_p->mp_fd, mp_p->mp_top); + if (mem == (void *)MAP_FAILED) { + if (errno == ENOMEM) { + SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); + } + else { + SET_POINTER(error_p, MPOOL_ERROR_MMAP); + } + return NULL; + } + mp_p->mp_top += size; + if (mp_p->mp_addr != NULL) { + mp_p->mp_addr = (char *)mp_p->mp_addr + size; + } + } + + mp_p->mp_page_c += page_n; + + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return mem; +} + +/* + * static int free_pages + * + * DESCRIPTION: + * + * Free previously allocated pages of memory. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * pages <-> Pointer to memory pages that we are freeing. + * + * size -> Size of the block that we are freeing. + * + * sbrk_b -> Set to one if the pages were allocated with sbrk else mmap. + */ +static int free_pages(void *pages, const unsigned long size, + const int sbrk_b) +{ + if (! sbrk_b) { + (void)munmap((caddr_t)pages, size); + } + + return MPOOL_ERROR_NONE; +} + +/* + * static int check_magic + * + * DESCRIPTION: + * + * Check for the existance of the magic ID in a memory pointer. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * addr -> Address inside of the block that we are tryign to locate. + * + * size -> Size of the block. + */ +static int check_magic(const void *addr, const unsigned long size) +{ + const unsigned char *mem_p; + + /* set our starting point */ + mem_p = (unsigned char *)addr + size; + + if (*mem_p == FENCE_MAGIC0 && *(mem_p + 1) == FENCE_MAGIC1) { + return MPOOL_ERROR_NONE; + } + else { + return MPOOL_ERROR_PNT_OVER; + } +} + +/* + * static void write_magic + * + * DESCRIPTION: + * + * Write the magic ID to the address. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * addr -> Address where to write the magic. + */ +static void write_magic(const void *addr) +{ + *(unsigned char *)addr = FENCE_MAGIC0; + *((unsigned char *)addr + 1) = FENCE_MAGIC1; +} + +/* + * static void free_pointer + * + * DESCRIPTION: + * + * Moved a pointer into our free lists. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * addr <-> Address where to write the magic. We may write a next + * pointer to it. + * + * size -> Size of the address space. + */ +static int free_pointer(mpool_t *mp_p, void *addr, + const unsigned long size) +{ + unsigned int bit_n; + unsigned long real_size; + mpool_free_t free_pnt; + +#ifdef DEBUG + (void)printf("freeing a block at %lx of %lu bytes\n", (long)addr, size); +#endif + + if (size == 0) { + return MPOOL_ERROR_NONE; + } + + /* + * if the user size is larger then can fit in an entire block then + * we change the size + */ + if (size > MAX_BLOCK_USER_MEMORY(mp_p)) { + real_size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, size)) - + sizeof(mpool_block_t); + } + else { + real_size = size; + } + + /* + * We use a specific free bits calculation here because if we are + * freeing 10 bytes then we will be putting it into the 8-byte free + * list and not the 16 byte list. size_to_bits(10) will return 4 + * instead of 3. + */ + bit_n = size_to_free_bits(real_size); + + /* + * Minimal error checking. We could go all the way through the + * list however this might be prohibitive. + */ + if (mp_p->mp_free[bit_n] == addr) { + return MPOOL_ERROR_IS_FREE; + } + + /* add the freed pointer to the free list */ + if (bit_n < min_bit_free_next) { + /* + * Yes we know this will lose 99% of the allocations but what else + * can we do? No space for a next pointer. + */ + if (mp_p->mp_free[bit_n] == NULL) { + mp_p->mp_free[bit_n] = addr; + } + } + else if (bit_n < min_bit_free_size) { + /* we copy, not assign, to maintain the free list */ + memcpy(addr, mp_p->mp_free + bit_n, sizeof(void *)); + mp_p->mp_free[bit_n] = addr; + } + else { + + /* setup our free list structure */ + free_pnt.mf_next_p = mp_p->mp_free[bit_n]; + free_pnt.mf_size = real_size; + + /* we copy the structure in since we don't know about alignment */ + memcpy(addr, &free_pnt, sizeof(free_pnt)); + mp_p->mp_free[bit_n] = addr; + } + + return MPOOL_ERROR_NONE; +} + +/* + * static int split_block + * + * DESCRIPTION: + * + * When freeing space in a multi-block chunk we have to create new + * blocks out of the upper areas being freed. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * free_addr -> Address that we are freeing. + * + * size -> Size of the space that we are taking from address. + */ +static int split_block(mpool_t *mp_p, void *free_addr, + const unsigned long size) +{ + mpool_block_t *block_p, *new_block_p; + int ret, page_n; + void *end_p; + + /* + * 1st we find the block pointer from our free addr. At this point + * the pointer must be the 1st one in the block if it is spans + * multiple blocks. + */ + block_p = (mpool_block_t *)((char *)free_addr - sizeof(mpool_block_t)); + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + page_n = PAGES_IN_SIZE(mp_p, size); + + /* we are creating a new block structure for the 2nd ... */ + new_block_p = (mpool_block_t *)((char *)block_p + + SIZE_OF_PAGES(mp_p, page_n)); + new_block_p->mb_magic = BLOCK_MAGIC; + /* New bounds is 1st block bounds. The 1st block's is reset below. */ + new_block_p->mb_bounds_p = block_p->mb_bounds_p; + /* Continue the linked list. The 1st block will point to us below. */ + new_block_p->mb_next_p = block_p->mb_next_p; + new_block_p->mb_magic2 = BLOCK_MAGIC; + + /* bounds for the 1st block are reset to the 1st page only */ + block_p->mb_bounds_p = (char *)new_block_p; + /* the next block pointer for the 1st block is now the new one */ + block_p->mb_next_p = new_block_p; + + /* only free the space in the 1st block if it is only 1 block in size */ + if (page_n == 1) { + /* now free the rest of the 1st block block */ + end_p = (char *)free_addr + size; + ret = free_pointer(mp_p, end_p, + (char *)block_p->mb_bounds_p - (char *)end_p); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + } + + /* now free the rest of the block */ + ret = free_pointer(mp_p, FIRST_ADDR_IN_BLOCK(new_block_p), + MEMORY_IN_BLOCK(new_block_p)); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + + return MPOOL_ERROR_NONE; +} + +/* + * static void *get_space + * + * DESCRIPTION: + * + * Moved a pointer into our free lists. + * + * RETURNS: + * + * Success - New address that we can use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * byte_size -> Size of the address space that we need. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +static void *get_space(mpool_t *mp_p, const unsigned long byte_size, + int *error_p) +{ + mpool_block_t *block_p; + mpool_free_t free_pnt; + int ret; + unsigned long size; + unsigned int bit_c, page_n, left; + void *free_addr = NULL, *free_end; + + size = byte_size; + while ((size & (sizeof(void *) - 1)) > 0) { + size++; + } + + /* + * First we check the free lists looking for something with enough + * pages. Maybe we should only look X bits higher in the list. + * + * XXX: this is where we'd do the best fit. We'd look for the + * closest match. We then could put the rest of the allocation that + * we did not use in a lower free list. Have a define which states + * how deep in the free list to go to find the closest match. + */ + for (bit_c = size_to_bits(size); bit_c <= MAX_BITS; bit_c++) { + if (mp_p->mp_free[bit_c] != NULL) { + free_addr = mp_p->mp_free[bit_c]; + break; + } + } + + /* + * If we haven't allocated any blocks or if the last block doesn't + * have enough memory then we need a new block. + */ + if (bit_c > MAX_BITS) { + + /* we need to allocate more space */ + + page_n = PAGES_IN_SIZE(mp_p, size); + + /* now we try and get the pages we need/want */ + block_p = alloc_pages(mp_p, page_n, error_p); + if (block_p == NULL) { + /* error_p set in alloc_pages */ + return NULL; + } + + /* init the block header */ + block_p->mb_magic = BLOCK_MAGIC; + block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(mp_p, page_n); + block_p->mb_next_p = mp_p->mp_first_p; + block_p->mb_magic2 = BLOCK_MAGIC; + + /* + * We insert it into the front of the queue. We could add it to + * the end but there is not much use. + */ + mp_p->mp_first_p = block_p; + if (mp_p->mp_last_p == NULL) { + mp_p->mp_last_p = block_p; + } + + free_addr = FIRST_ADDR_IN_BLOCK(block_p); + +#ifdef DEBUG + (void)printf("had to allocate space for %lx of %lu bytes\n", + (long)free_addr, size); +#endif + + free_end = (char *)free_addr + size; + left = (char *)block_p->mb_bounds_p - (char *)free_end; + } + else { + + if (bit_c < min_bit_free_next) { + mp_p->mp_free[bit_c] = NULL; + /* calculate the number of left over bytes */ + left = bits_to_size(bit_c) - size; + } + else if (bit_c < min_bit_free_next) { + /* grab the next pointer from the freed address into our list */ + memcpy(mp_p->mp_free + bit_c, free_addr, sizeof(void *)); + /* calculate the number of left over bytes */ + left = bits_to_size(bit_c) - size; + } + else { + /* grab the free structure from the address */ + memcpy(&free_pnt, free_addr, sizeof(free_pnt)); + mp_p->mp_free[bit_c] = free_pnt.mf_next_p; + + /* are we are splitting up a multiblock chunk into fewer blocks? */ + if (PAGES_IN_SIZE(mp_p, free_pnt.mf_size) > PAGES_IN_SIZE(mp_p, size)) { + ret = split_block(mp_p, free_addr, size); + if (ret != MPOOL_ERROR_NONE) { + SET_POINTER(error_p, ret); + return NULL; + } + /* left over memory was taken care of in split_block */ + left = 0; + } + else { + /* calculate the number of left over bytes */ + left = free_pnt.mf_size - size; + } + } + +#ifdef DEBUG + (void)printf("found a free block at %lx of %lu bytes\n", + (long)free_addr, left + size); +#endif + + free_end = (char *)free_addr + size; + } + + /* + * If we have memory left over then we free it so someone else can + * use it. We do not free the space if we just allocated a + * multi-block chunk because we need to have every allocation easily + * find the start of the block. Every user address % page-size + * should take us to the start of the block. + */ + if (left > 0 && size <= MAX_BLOCK_USER_MEMORY(mp_p)) { + /* free the rest of the block */ + ret = free_pointer(mp_p, free_end, left); + if (ret != MPOOL_ERROR_NONE) { + SET_POINTER(error_p, ret); + return NULL; + } + } + + /* update our bounds */ + if (free_addr > mp_p->mp_bounds_p) { + mp_p->mp_bounds_p = free_addr; + } + else if (free_addr < mp_p->mp_min_p) { + mp_p->mp_min_p = free_addr; + } + + return free_addr; +} + +/* + * static void *alloc_mem + * + * DESCRIPTION: + * + * Allocate space for bytes inside of an already open memory pool. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal malloc. + * + * byte_size -> Number of bytes to allocate in the pool. Must be >0. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +static void *alloc_mem(mpool_t *mp_p, const unsigned long byte_size, + int *error_p) +{ + unsigned long size, fence; + void *addr; + + /* make sure we have enough bytes */ + if (byte_size < MIN_ALLOCATION) { + size = MIN_ALLOCATION; + } + else { + size = byte_size; + } + + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + fence = 0; + } + else { + fence = FENCE_SIZE; + } + + /* get our free space + the space for the fence post */ + addr = get_space(mp_p, size + fence, error_p); + if (addr == NULL) { + /* error_p set in get_space */ + return NULL; + } + + if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + write_magic((char *)addr + size); + } + + /* maintain our stats */ + mp_p->mp_alloc_c++; + mp_p->mp_user_alloc += size; + if (mp_p->mp_user_alloc > mp_p->mp_max_alloc) { + mp_p->mp_max_alloc = mp_p->mp_user_alloc; + } + + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return addr; +} + +/* + * static int free_mem + * + * DESCRIPTION: + * + * Free an address from a memory pool. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal free. + * + * addr <-> Address to free. + * + * size -> Size of the address being freed. + */ +static int free_mem(mpool_t *mp_p, void *addr, const unsigned long size) +{ + unsigned long old_size, fence; + int ret; + mpool_block_t *block_p; + + /* + * If the size is larger than a block then the allocation must be at + * the front of the block. + */ + if (size > MAX_BLOCK_USER_MEMORY(mp_p)) { + block_p = (mpool_block_t *)((char *)addr - sizeof(mpool_block_t)); + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + } + + /* make sure we have enough bytes */ + if (size < MIN_ALLOCATION) { + old_size = MIN_ALLOCATION; + } + else { + old_size = size; + } + + /* if we are packing the pool smaller */ + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + fence = 0; + } + else { + /* find the user's magic numbers if they were written */ + ret = check_magic(addr, old_size); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + fence = FENCE_SIZE; + } + + /* now we free the pointer */ + ret = free_pointer(mp_p, addr, old_size + fence); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + mp_p->mp_user_alloc -= old_size; + + /* adjust our stats */ + mp_p->mp_alloc_c--; + + return MPOOL_ERROR_NONE; +} + +/***************************** exported routines *****************************/ + +/* + * mpool_t *mpool_open + * + * DESCRIPTION: + * + * Open/allocate a new memory pool. + * + * RETURNS: + * + * Success - Pool pointer which must be passed to mpool_close to + * deallocate. + * + * Failure - NULL + * + * ARGUMENTS: + * + * flags -> Flags to set attributes of the memory pool. See the top + * of mpool.h. + * + * page_size -> Set the internal memory page-size. This must be a + * multiple of the getpagesize() value. Set to 0 for the default. + * + * start_addr -> Starting address to try and allocate memory pools. + * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, + void *start_addr, int *error_p) +{ + mpool_block_t *block_p; + int page_n, ret; + mpool_t mp, *mp_p; + void *free_addr; + + if (! enabled_b) { + startup(); + } + + /* zero our temp struct */ + memset(&mp, 0, sizeof(mp)); + + mp.mp_magic = MPOOL_MAGIC; + mp.mp_flags = flags; + mp.mp_alloc_c = 0; + mp.mp_user_alloc = 0; + mp.mp_max_alloc = 0; + mp.mp_page_c = 0; + /* mp.mp_page_size set below */ + /* mp.mp_blocks_bit_n set below */ + /* mp.mp_fd set below */ + /* mp.mp_top set below */ + /* mp.mp_addr set below */ + mp.mp_log_func = NULL; + mp.mp_min_p = NULL; + mp.mp_bounds_p = NULL; + mp.mp_first_p = NULL; + mp.mp_last_p = NULL; + mp.mp_magic2 = MPOOL_MAGIC; + + /* get and sanity check our page size */ + if (page_size > 0) { + mp.mp_page_size = page_size; + if (mp.mp_page_size % getpagesize() != 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } + } + else { + mp.mp_page_size = getpagesize() * DEFAULT_PAGE_MULT; + if (mp.mp_page_size % 1024 != 0) { + SET_POINTER(error_p, MPOOL_ERROR_PAGE_SIZE); + return NULL; + } + } + + if (BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)) { + mp.mp_fd = -1; + mp.mp_addr = NULL; + mp.mp_top = 0; + } + else { + /* open dev-zero for our mmaping */ + mp.mp_fd = open("/dev/zero", O_RDWR, 0); + if (mp.mp_fd < 0) { + SET_POINTER(error_p, MPOOL_ERROR_OPEN_ZERO); + return NULL; + } + mp.mp_addr = start_addr; + /* we start at the front of the file */ + mp.mp_top = 0; + } + + /* + * Find out how many pages we need for our mpool structure. + * + * NOTE: this adds possibly unneeded space for mpool_block_t which + * may not be in this block. + */ + page_n = PAGES_IN_SIZE(&mp, sizeof(mpool_t)); + + /* now allocate us space for the actual struct */ + mp_p = alloc_pages(&mp, page_n, error_p); + if (mp_p == NULL) { + if (mp.mp_fd >= 0) { + (void)close(mp.mp_fd); + mp.mp_fd = -1; + } + return NULL; + } + + /* + * NOTE: we do not normally free the rest of the block here because + * we want to lesson the chance of an allocation overwriting the + * main structure. + */ + if (BIT_IS_SET(flags, MPOOL_FLAG_HEAVY_PACKING)) { + + /* we add a block header to the front of the block */ + block_p = (mpool_block_t *)mp_p; + + /* init the block header */ + block_p->mb_magic = BLOCK_MAGIC; + block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(&mp, page_n); + block_p->mb_next_p = NULL; + block_p->mb_magic2 = BLOCK_MAGIC; + + /* the mpool pointer is then the 2nd thing in the block */ + mp_p = FIRST_ADDR_IN_BLOCK(block_p); + free_addr = (char *)mp_p + sizeof(mpool_t); + + /* free the rest of the block */ + ret = free_pointer(&mp, free_addr, + (char *)block_p->mb_bounds_p - (char *)free_addr); + if (ret != MPOOL_ERROR_NONE) { + if (mp.mp_fd >= 0) { + (void)close(mp.mp_fd); + mp.mp_fd = -1; + } + /* NOTE: after this line mp_p will be invalid */ + (void)free_pages(block_p, SIZE_OF_PAGES(&mp, page_n), + BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)); + SET_POINTER(error_p, ret); + return NULL; + } + + /* + * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool + * header is not on the block linked list. + */ + + /* now copy our tmp structure into our new memory area */ + memcpy(mp_p, &mp, sizeof(mpool_t)); + + /* we setup min/max to our current address which is as good as any */ + mp_p->mp_min_p = block_p; + mp_p->mp_bounds_p = block_p->mb_bounds_p; + } + else { + /* now copy our tmp structure into our new memory area */ + memcpy(mp_p, &mp, sizeof(mpool_t)); + + /* we setup min/max to our current address which is as good as any */ + mp_p->mp_min_p = mp_p; + mp_p->mp_bounds_p = (char *)mp_p + SIZE_OF_PAGES(mp_p, page_n); + } + + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return mp_p; +} + +/* + * int mpool_close + * + * DESCRIPTION: + * + * Close/free a memory allocation pool previously opened with + * mpool_open. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to our memory pool. + */ +int mpool_close(mpool_t *mp_p) +{ + mpool_block_t *block_p, *next_p; + void *addr; + unsigned long size; + int ret, final = MPOOL_ERROR_NONE; + + /* special case, just return no-error */ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLOSE, 0, 0, NULL, NULL, 0); + } + + /* + * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool + * header is not on the linked list. + */ + + /* free/invalidate the blocks */ + for (block_p = mp_p->mp_first_p; block_p != NULL; block_p = next_p) { + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + final = MPOOL_ERROR_POOL_OVER; + break; + } + block_p->mb_magic = 0; + block_p->mb_magic2 = 0; + /* record the next pointer because it might be invalidated below */ + next_p = block_p->mb_next_p; + ret = free_pages(block_p, (char *)block_p->mb_bounds_p - (char *)block_p, + BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)); + if (ret != MPOOL_ERROR_NONE) { + final = ret; + } + } + + /* close /dev/zero if necessary */ + if (mp_p->mp_fd >= 0) { + (void)close(mp_p->mp_fd); + mp_p->mp_fd = -1; + } + + /* invalidate the mpool before we ditch it */ + mp_p->mp_magic = 0; + mp_p->mp_magic2 = 0; + + /* last we munmap the mpool pointer itself */ + if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) { + + /* if we are heavy packing then we need to free the 1st block later */ + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) { + addr = (char *)mp_p - sizeof(mpool_block_t); + } + else { + addr = mp_p; + } + size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, sizeof(mpool_t))); + + (void)munmap((caddr_t)addr, size); + } + + return final; +} + +/* + * int mpool_clear + * + * DESCRIPTION: + * + * Wipe an opened memory pool clean so we can start again. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to our memory pool. + */ +int mpool_clear(mpool_t *mp_p) +{ + mpool_block_t *block_p; + int final = MPOOL_ERROR_NONE, bit_n, ret; + void *first_p; + + /* special case, just return no-error */ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLEAR, 0, 0, NULL, NULL, 0); + } + + /* reset all of our free lists */ + for (bit_n = 0; bit_n <= MAX_BITS; bit_n++) { + mp_p->mp_free[bit_n] = NULL; + } + + /* free the blocks */ + for (block_p = mp_p->mp_first_p; + block_p != NULL; + block_p = block_p->mb_next_p) { + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + final = MPOOL_ERROR_POOL_OVER; + break; + } + + first_p = FIRST_ADDR_IN_BLOCK(block_p); + + /* free the memory */ + ret = free_pointer(mp_p, first_p, MEMORY_IN_BLOCK(block_p)); + if (ret != MPOOL_ERROR_NONE) { + final = ret; + } + } + + return final; +} + +/* + * void *mpool_alloc + * + * DESCRIPTION: + * + * Allocate space for bytes inside of an already open memory pool. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool + * + * byte_size -> Number of bytes to allocate in the pool. Must be >0. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, + int *error_p) +{ + struct FRAG *frag; + + if (!mp_p || mp_p->mp_magic != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_PNT); + return NULL; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } + + if (byte_size == 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } + + frag = (struct FRAG *)alloc_mem(mp_p, byte_size + FRAG_OVERHEAD, error_p); + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_ALLOC, byte_size, 0, (void *)frag, NULL, 0); + } + + frag->frag_size = byte_size; + return &frag->frag_ptr; +} + +/* + * void *mpool_calloc + * + * DESCRIPTION: + * + * Allocate space for elements of bytes in the memory pool and zero + * the space afterwards. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * ele_n -> Number of elements to allocate. + * + * ele_size -> Number of bytes per element being allocated. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, + const unsigned long ele_size, int *error_p) +{ + struct FRAG *frag; + unsigned long byte_size; + + if (!mp_p || mp_p->mp_magic != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_PNT); + return NULL; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } + + if (ele_n == 0 || ele_size == 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } + + byte_size = ele_n * ele_size; + + frag = alloc_mem(mp_p, byte_size + FRAG_OVERHEAD, error_p); + if (frag != NULL) { + memset(&frag->frag_ptr, 0, byte_size); + } + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_CALLOC, ele_size, ele_n, (void *)frag, NULL, 0); + } + + frag->frag_size = byte_size; + return &frag->frag_ptr; +} + +/* + * int mpool_free + * + * DESCRIPTION: + * + * Free an address from a memory pool. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * addr <-> Address to free. + * + * size -> Size of the address being freed. + */ +int mpool_free(mpool_t *mp_p, void *addr) +{ + struct FRAG *frag = (struct FRAG *) (addr - FRAG_OVERHEAD); + + if (!mp_p || mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_FREE, 0, 0, NULL, addr, 0); + } + + if (addr == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + + return free_mem(mp_p, (void *)frag, frag->frag_size + FRAG_OVERHEAD); +} + +/* + * void *mpool_resize + * + * DESCRIPTION: + * + * Reallocate an address in a mmeory pool to a new size. This is + * different from realloc in that it needs the old address' size. If + * you don't have it then you need to allocate new space, copy the + * data, and free the old pointer yourself. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal realloc. + * + * old_addr -> Previously allocated address. + * + * old_byte_size -> Size of the old address. Must be known, cannot be + * 0. + * + * new_byte_size -> New size of the allocation. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +void *mpool_resize(mpool_t *mp_p, void *old_addr, + const unsigned long new_byte_size, + int *error_p) +{ + unsigned long copy_size, new_size, old_size, fence; + struct FRAG *new_frag; + mpool_block_t *block_p; + int ret; + struct FRAG *old_frag = (struct FRAG *)(old_addr - FRAG_OVERHEAD); + unsigned long old_byte_size; + + if (!mp_p || mp_p->mp_magic != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_PNT); + return NULL; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } + + if (old_addr == NULL) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_NULL); + return NULL; + } + + old_byte_size = old_frag->frag_size; + if (old_byte_size == 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } + + /* + * If the size is larger than a block then the allocation must be at + * the front of the block. + */ + if (old_byte_size + FRAG_OVERHEAD > MAX_BLOCK_USER_MEMORY(mp_p)) { + block_p = (mpool_block_t *)((char *)old_frag - sizeof(mpool_block_t)); + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } + } + + /* make sure we have enough bytes */ + if (old_byte_size + FRAG_OVERHEAD < MIN_ALLOCATION) { + old_size = MIN_ALLOCATION; + } + else { + old_size = old_byte_size + FRAG_OVERHEAD; + } + + /* verify that the size matches exactly if we can */ + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + fence = 0; + } + else if (old_size > 0) { + ret = check_magic((void *)old_frag, old_size); + if (ret != MPOOL_ERROR_NONE) { + SET_POINTER(error_p, ret); + return NULL; + } + fence = FENCE_SIZE; + } + + /* make sure we have enough bytes */ + if (new_byte_size < MIN_ALLOCATION) { + new_size = MIN_ALLOCATION; + } + else { + new_size = new_byte_size; + } + + /* + * NOTE: we could here see if the size is the same or less and then + * use the current memory and free the space above. This is harder + * than it sounds if we are changing the block size of the + * allocation. + */ + + /* we need to get another address */ + new_frag = alloc_mem(mp_p, new_byte_size + FRAG_OVERHEAD, error_p); + if (new_frag == NULL) { + /* error_p set in mpool_alloc */ + return NULL; + } + + if (new_byte_size > old_byte_size) { + copy_size = old_byte_size; + } + else { + copy_size = new_byte_size; + } + new_frag->frag_size = new_byte_size; + memcpy(&new_frag->frag_ptr, old_addr, copy_size); + + /* free the old address */ + ret = free_mem(mp_p, (void *)old_frag, old_byte_size + FRAG_OVERHEAD); + if (ret != MPOOL_ERROR_NONE) { + /* if the old free failed, try and free the new address */ + (void)free_mem(mp_p, (void *)new_frag, new_byte_size + FRAG_OVERHEAD); + SET_POINTER(error_p, ret); + return NULL; + } + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_RESIZE, new_byte_size, + 0, (void *)new_frag, old_addr, old_byte_size); + } + + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return &new_frag->frag_ptr; +} + +/* + * int mpool_stats + * + * DESCRIPTION: + * + * Return stats from the memory pool. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p -> Pointer to the memory pool. + * + * page_size_p <- Pointer to an unsigned integer which, if not NULL, + * will be set to the page-size of the pool. + * + * num_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the number of pointers currently allocated in pool. + * + * user_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the number of user bytes allocated in this pool. + * + * max_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the maximum number of user bytes that have been + * allocated in this pool. + * + * tot_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the total amount of space (including administrative + * overhead) used by the pool. + */ +int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, + unsigned long *num_alloced_p, + unsigned long *user_alloced_p, + unsigned long *max_alloced_p, + unsigned long *tot_alloced_p) +{ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + SET_POINTER(page_size_p, mp_p->mp_page_size); + SET_POINTER(num_alloced_p, mp_p->mp_alloc_c); + SET_POINTER(user_alloced_p, mp_p->mp_user_alloc); + SET_POINTER(max_alloced_p, mp_p->mp_max_alloc); + SET_POINTER(tot_alloced_p, SIZE_OF_PAGES(mp_p, mp_p->mp_page_c)); + + return MPOOL_ERROR_NONE; +} + +/* + * int mpool_set_log_func + * + * DESCRIPTION: + * + * Set a logging callback function to be called whenever there was a + * memory transaction. See mpool_log_func_t. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * log_func -> Log function (defined in mpool.h) which will be called + * with each mpool transaction. + */ +int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func) +{ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + mp_p->mp_log_func = log_func; + + return MPOOL_ERROR_NONE; +} + +/* + * int mpool_set_max_pages + * + * DESCRIPTION: + * + * Set the maximum number of pages that the library will use. Once it + * hits the limit it will return MPOOL_ERROR_NO_PAGES. + * + * NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages + * value will include the page with the mpool header structure in it. + * If the flag is _not_ set then the max-pages will not include this + * first page. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * max_pages -> Maximum number of pages used by the library. + */ +int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages) +{ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) { + mp_p->mp_max_pages = max_pages; + } + else { + /* + * If we are not heavy-packing the pool then we don't count the + * 1st page allocated which holds the mpool header structure. + */ + mp_p->mp_max_pages = max_pages + 1; + } + + return MPOOL_ERROR_NONE; +} + +/* + * const char *mpool_strerror + * + * DESCRIPTION: + * + * Return the corresponding string for the error number. + * + * RETURNS: + * + * Success - String equivalient of the error. + * + * Failure - String "invalid error code" + * + * ARGUMENTS: + * + * error -> Error number that we are converting. + */ +const char *mpool_strerror(const int error) +{ + switch (error) { + case MPOOL_ERROR_NONE: + return "no error"; + break; + case MPOOL_ERROR_ARG_NULL: + return "function argument is null"; + break; + case MPOOL_ERROR_ARG_INVALID: + return "function argument is invalid"; + break; + case MPOOL_ERROR_PNT: + return "invalid mpool pointer"; + break; + case MPOOL_ERROR_POOL_OVER: + return "mpool structure was overwritten"; + break; + case MPOOL_ERROR_PAGE_SIZE: + return "could not get system page-size"; + break; + case MPOOL_ERROR_OPEN_ZERO: + return "could not open /dev/zero"; + break; + case MPOOL_ERROR_NO_MEM: + return "no memory available"; + break; + case MPOOL_ERROR_MMAP: + return "problems with mmap"; + break; + case MPOOL_ERROR_SIZE: + return "error processing requested size"; + break; + case MPOOL_ERROR_TOO_BIG: + return "allocation exceeds pool max size"; + break; + case MPOOL_ERROR_MEM: + return "invalid memory address"; + break; + case MPOOL_ERROR_MEM_OVER: + return "memory lower bounds overwritten"; + break; + case MPOOL_ERROR_NOT_FOUND: + return "memory block not found in pool"; + break; + case MPOOL_ERROR_IS_FREE: + return "memory address has already been freed"; + break; + case MPOOL_ERROR_BLOCK_STAT: + return "invalid internal block status"; + break; + case MPOOL_ERROR_FREE_ADDR: + return "invalid internal free address"; + break; + case MPOOL_ERROR_SBRK_CONTIG: + return "sbrk did not return contiguous memory"; + break; + case MPOOL_ERROR_NO_PAGES: + return "no available pages left in pool"; + break; + case MPOOL_ERROR_ALLOC: + return "system alloc function failed"; + break; + case MPOOL_ERROR_PNT_OVER: + return "user pointer admin space overwritten"; + break; + default: + break; + } + + return "invalid error code"; +} diff --git a/libclamav/mpool-2.1.0/mpool.h b/libclamav/mpool-2.1.0/mpool.h new file mode 100644 index 000000000..5d8a8f528 --- /dev/null +++ b/libclamav/mpool-2.1.0/mpool.h @@ -0,0 +1,462 @@ +/* + * Memory pool defines. + * + * Copyright 1996 by Gray Watson. + * + * This file is part of the mpool package. + * + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies, and that the name of Gray Watson not be used in advertising + * or publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: mpool.h,v 1.4 2006/05/31 20:26:11 gray Exp $ + */ + +#ifndef __MPOOL_H__ +#define __MPOOL_H__ + +#include + +/* + * mpool flags to mpool_alloc or mpool_set_attr + */ + +/* + * Choose a best fit algorithm not first fit. This takes more CPU + * time but will result in a tighter heap. + */ +#define MPOOL_FLAG_BEST_FIT (1<<0) + +/* + * By default the library adds 2 bytes onto all allocations to insert + * a magic number that it can look for to determine how large a freed + * memory chunk is. This flag indicates that few if any frees are + * going to be performed on the pool and to not waste memory on these + * bytes. + */ +#define MPOOL_FLAG_NO_FREE (1<<1) + +/* + * This enables very heavy packing at the possible expense of CPU. + * This affects a number of parts of the library. + * + * By default the 1st page of memory is reserved for the main mpool + * structure. This flag will cause the rest of the 1st block to be + * available for use as user memory. + * + * By default the library looks through the memory when freed looking + * for a magic value. There is an internal max size that it will look + * and then it will give up. This flag forces it to look until it + * finds it. + */ +#define MPOOL_FLAG_HEAVY_PACKING (1<<2) + +/* + * Use sbrk not mmap to allocate pages. This is not recommended for + * normal use. + */ +#define MPOOL_FLAG_USE_SBRK (1<<3) + +/* + * Mpool error codes + */ +#define MPOOL_ERROR_NONE 1 /* no error */ +#define MPOOL_ERROR_ARG_NULL 2 /* function argument is null */ +#define MPOOL_ERROR_ARG_INVALID 3 /* function argument is invalid */ +#define MPOOL_ERROR_PNT 4 /* invalid mpool pointer */ +#define MPOOL_ERROR_POOL_OVER 5 /* mpool structure was overwritten */ +#define MPOOL_ERROR_PAGE_SIZE 6 /* could not get system page-size */ +#define MPOOL_ERROR_OPEN_ZERO 7 /* could not open /dev/zero */ +#define MPOOL_ERROR_NO_MEM 8 /* no memory available */ +#define MPOOL_ERROR_MMAP 9 /* problems with mmap */ +#define MPOOL_ERROR_SIZE 10 /* error processing requested size */ +#define MPOOL_ERROR_TOO_BIG 11 /* allocation exceeded max size */ +#define MPOOL_ERROR_MEM 12 /* invalid memory address */ +#define MPOOL_ERROR_MEM_OVER 13 /* memory lower bounds overwritten */ +#define MPOOL_ERROR_NOT_FOUND 14 /* memory block not found in pool */ +#define MPOOL_ERROR_IS_FREE 15 /* memory block already free */ +#define MPOOL_ERROR_BLOCK_STAT 16 /* invalid internal block status */ +#define MPOOL_ERROR_FREE_ADDR 17 /* invalid internal free address */ +#define MPOOL_ERROR_SBRK_CONTIG 18 /* sbrk did not return contiguous mem*/ +#define MPOOL_ERROR_NO_PAGES 19 /* ran out of pages in pool */ +#define MPOOL_ERROR_ALLOC 20 /* calloc,malloc,free,realloc failed */ +#define MPOOL_ERROR_PNT_OVER 21 /* pointer structure was overwritten */ + +/* + * Mpool function IDs for the mpool_log_func callback function. + */ +#define MPOOL_FUNC_CLOSE 1 /* mpool_close function called */ +#define MPOOL_FUNC_CLEAR 2 /* mpool_clear function called */ +#define MPOOL_FUNC_ALLOC 3 /* mpool_alloc function called */ +#define MPOOL_FUNC_CALLOC 4 /* mpool_calloc function called */ +#define MPOOL_FUNC_FREE 5 /* mpool_free function called */ +#define MPOOL_FUNC_RESIZE 6 /* mpool_resize function called */ + +/* + * void mpool_log_func_t + * + * DESCRIPTION: + * + * Mpool transaction log function. + * + * RETURNS: + * + * None. + * + * ARGUMENT: + * + * mp_p -> Associated mpool address. + * + * func_id -> Integer function ID which identifies which mpool + * function is being called. + * + * byte_size -> Optionally specified byte size. + * + * ele_n -> Optionally specified element number. For mpool_calloc + * only. + * + * new_addr -> Optionally specified new address. For mpool_alloc, + * mpool_calloc, and mpool_resize only. + * + * old_addr -> Optionally specified old address. For mpool_resize and + * mpool_free only. + * + * old_byte_size -> Optionally specified old byte size. For + * mpool_resize only. + */ +typedef void (*mpool_log_func_t)(const void *mp_p, + const int func_id, + const unsigned long byte_size, + const unsigned long ele_n, + const void *old_addr, const void *new_addr, + const unsigned long old_byte_size); + +#ifdef MPOOL_MAIN + +#include "mpool_loc.h" + +#else + +/* generic mpool type */ +typedef void mpool_t; + +#endif + +/*<<<<<<<<<< The below prototypes are auto-generated by fillproto */ + +/* + * mpool_t *mpool_open + * + * DESCRIPTION: + * + * Open/allocate a new memory pool. + * + * RETURNS: + * + * Success - Pool pointer which must be passed to mpool_close to + * deallocate. + * + * Failure - NULL + * + * ARGUMENTS: + * + * flags -> Flags to set attributes of the memory pool. See the top + * of mpool.h. + * + * page_size -> Set the internal memory page-size. This must be a + * multiple of the getpagesize() value. Set to 0 for the default. + * + * start_addr -> Starting address to try and allocate memory pools. + * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +extern +mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, + void *start_addr, int *error_p); + +/* + * int mpool_close + * + * DESCRIPTION: + * + * Close/free a memory allocation pool previously opened with + * mpool_open. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to our memory pool. + */ +extern +int mpool_close(mpool_t *mp_p); + +/* + * int mpool_clear + * + * DESCRIPTION: + * + * Wipe an opened memory pool clean so we can start again. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to our memory pool. + */ +extern +int mpool_clear(mpool_t *mp_p); + +/* + * void *mpool_alloc + * + * DESCRIPTION: + * + * Allocate space for bytes inside of an already open memory pool. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal malloc. + * + * byte_size -> Number of bytes to allocate in the pool. Must be >0. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +extern +void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, + int *error_p); + +/* + * void *mpool_calloc + * + * DESCRIPTION: + * + * Allocate space for elements of bytes in the memory pool and zero + * the space afterwards. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal calloc. + * + * ele_n -> Number of elements to allocate. + * + * ele_size -> Number of bytes per element being allocated. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +extern +void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, + const unsigned long ele_size, int *error_p); + +/* + * int mpool_free + * + * DESCRIPTION: + * + * Free an address from a memory pool. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal free. + * + * addr <-> Address to free. + * + * size -> Size of the address being freed. + */ +extern +int mpool_free(mpool_t *mp_p, void *addr); + +/* + * void *mpool_resize + * + * DESCRIPTION: + * + * Reallocate an address in a mmeory pool to a new size. This is + * different from realloc in that it needs the old address' size. If + * you don't have it then you need to allocate new space, copy the + * data, and free the old pointer yourself. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal realloc. + * + * old_addr -> Previously allocated address. + * + * old_byte_size -> Size of the old address. Must be known, cannot be + * 0. + * + * new_byte_size -> New size of the allocation. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +extern +void *mpool_resize(mpool_t *mp_p, void *old_addr, + const unsigned long new_byte_size, + int *error_p); + +/* + * int mpool_stats + * + * DESCRIPTION: + * + * Return stats from the memory pool. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p -> Pointer to the memory pool. + * + * page_size_p <- Pointer to an unsigned integer which, if not NULL, + * will be set to the page-size of the pool. + * + * num_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the number of pointers currently allocated in pool. + * + * user_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the number of user bytes allocated in this pool. + * + * max_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the maximum number of user bytes that have been + * allocated in this pool. + * + * tot_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the total amount of space (including administrative + * overhead) used by the pool. + */ +extern +int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, + unsigned long *num_alloced_p, + unsigned long *user_alloced_p, + unsigned long *max_alloced_p, + unsigned long *tot_alloced_p); + +/* + * int mpool_set_log_func + * + * DESCRIPTION: + * + * Set a logging callback function to be called whenever there was a + * memory transaction. See mpool_log_func_t. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * log_func -> Log function (defined in mpool.h) which will be called + * with each mpool transaction. + */ +extern +int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func); + +/* + * int mpool_set_max_pages + * + * DESCRIPTION: + * + * Set the maximum number of pages that the library will use. Once it + * hits the limit it will return MPOOL_ERROR_NO_PAGES. + * + * NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages + * value will include the page with the mpool header structure in it. + * If the flag is _not_ set then the max-pages will not include this + * first page. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * max_pages -> Maximum number of pages used by the library. + */ +extern +int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages); + +/* + * const char *mpool_strerror + * + * DESCRIPTION: + * + * Return the corresponding string for the error number. + * + * RETURNS: + * + * Success - String equivalient of the error. + * + * Failure - String "invalid error code" + * + * ARGUMENTS: + * + * error -> Error number that we are converting. + */ +extern +const char *mpool_strerror(const int error); + +/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ + +#endif /* ! __MPOOL_H__ */ diff --git a/libclamav/mpool-2.1.0/mpool_loc.h b/libclamav/mpool-2.1.0/mpool_loc.h new file mode 100644 index 000000000..3d33f5d92 --- /dev/null +++ b/libclamav/mpool-2.1.0/mpool_loc.h @@ -0,0 +1,116 @@ +/* + * Memory pool local defines. + * + * Copyright 1996 by Gray Watson. + * + * This file is part of the mpool package. + * + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies, and that the name of Gray Watson not be used in advertising + * or publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: mpool_loc.h,v 1.2 2005/05/20 20:08:54 gray Exp $ + */ + +#ifndef __MPOOL_LOC_H__ +#define __MPOOL_LOC_H__ + +#define MPOOL_MAGIC 0xABACABA /* magic for struct */ +#define BLOCK_MAGIC 0xB1B1007 /* magic for blocks */ +#define FENCE_MAGIC0 (unsigned char)(0xFAU) /* 1st magic mem byte */ +#define FENCE_MAGIC1 (unsigned char)(0xD3U) /* 2nd magic mem byte */ + +#define FENCE_SIZE 2 /* fence space */ +#define MIN_ALLOCATION (sizeof(mpool_free_t)) /* min alloc */ +#define MAX_FREE_SEARCH 10240 /* max size to search */ +#define MAX_FREE_LIST_SEARCH 100 /* max looking for free mem */ + +/* + * bitflag tools for Variable and a Flag + */ +#define BIT_FLAG(x) (1 << (x)) +#define BIT_SET(v,f) (v) |= (f) +#define BIT_CLEAR(v,f) (v) &= ~(f) +#define BIT_IS_SET(v,f) ((v) & (f)) +#define BIT_TOGGLE(v,f) (v) ^= (f) + +#define SET_POINTER(pnt, val) \ + do { \ + if ((pnt) != NULL) { \ + (*(pnt)) = (val); \ + } \ + } while(0) + +#define BLOCK_FLAG_USED BIT_FLAG(0) /* block is used */ +#define BLOCK_FLAG_FREE BIT_FLAG(1) /* block is free */ + +#define DEFAULT_PAGE_MULT 16 /* pagesize = this * getpagesize*/ + +/* How many pages SIZE bytes resides in. We add in the block header. */ +#define PAGES_IN_SIZE(mp_p, size) (((size) + sizeof(mpool_block_t) + \ + (mp_p)->mp_page_size - 1) / \ + (mp_p)->mp_page_size) +#define SIZE_OF_PAGES(mp_p, page_n) ((page_n) * (mp_p)->mp_page_size) +#define MAX_BITS 30 /* we only can allocate 1gb chunks */ + +#define MAX_BLOCK_USER_MEMORY(mp_p) ((mp_p)->mp_page_size - \ + sizeof(mpool_block_t)) +#define FIRST_ADDR_IN_BLOCK(block_p) (void *)((char *)(block_p) + \ + sizeof(mpool_block_t)) +#define MEMORY_IN_BLOCK(block_p) ((char *)(block_p)->mb_bounds_p - \ + ((char *)(block_p) + \ + sizeof(mpool_block_t))) + +typedef struct { + unsigned int mp_magic; /* magic number for struct */ + unsigned int mp_flags; /* flags for the struct */ + unsigned long mp_alloc_c; /* number of allocations */ + unsigned long mp_user_alloc; /* user bytes allocated */ + unsigned long mp_max_alloc; /* maximum user bytes allocated */ + unsigned int mp_page_c; /* number of pages allocated */ + unsigned int mp_max_pages; /* maximum number of pages to use */ + unsigned int mp_page_size; /* page-size of our system */ + int mp_fd; /* fd for /dev/zero if mmap-ing */ + off_t mp_top; /* top of our allocations in fd */ + mpool_log_func_t mp_log_func; /* log callback function */ + void *mp_addr; /* current address for mmaping */ + void *mp_min_p; /* min address in pool for checks */ + void *mp_bounds_p; /* max address in pool for checks */ + struct mpool_block_st *mp_first_p; /* first memory block we are using */ + struct mpool_block_st *mp_last_p; /* last memory block we are using */ + struct mpool_block_st *mp_free[MAX_BITS + 1]; /* free lists based on size */ + unsigned int mp_magic2; /* upper magic for overwrite sanity */ +} mpool_t; + +/* for debuggers to be able to interrogate the generic type in the .h file */ +typedef mpool_t mpool_ext_t; + +/* + * Block header structure. This structure *MUST* be long-word + * aligned. + */ +typedef struct mpool_block_st { + unsigned int mb_magic; /* magic number for block header */ + void *mb_bounds_p; /* block boundary location */ + struct mpool_block_st *mb_next_p; /* linked list next pointer */ + unsigned int mb_magic2; /* upper magic for overwrite sanity */ +} mpool_block_t; + +/* + * Free list structure. + */ +typedef struct { + void *mf_next_p; /* pointer to the next free address */ + unsigned long mf_size; /* size of the free block */ +} mpool_free_t; + +#endif /* ! __MPOOL_LOC_H__ */ diff --git a/libclamav/mpool-2.1.0/mpool_t.c b/libclamav/mpool-2.1.0/mpool_t.c new file mode 100644 index 000000000..37c25d218 --- /dev/null +++ b/libclamav/mpool-2.1.0/mpool_t.c @@ -0,0 +1,914 @@ +/* + * Memory pool test program. + * + * Copyright 1996 by Gray Watson. + * + * This file is part of the mpool package. + * + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies, and that the name of Gray Watson not be used in advertising + * or publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: mpool_t.c,v 1.2 2005/05/20 20:08:55 gray Exp $ + */ + +/* + * Test program for the malloc library. Current it is interactive although + * should be script based. + */ + +#include +#include +#include +#include +#include +#include + +#include "mpool.h" + +#ifdef __GNUC__ +#ident "$Id: mpool_t.c,v 1.2 2005/05/20 20:08:55 gray Exp $" +#else +static char *rcs_id = "$Id: mpool_t.c,v 1.2 2005/05/20 20:08:55 gray Exp $"; +#endif + +#define DEFAULT_ITERATIONS 10000 +#define MAX_POINTERS 1024 +#define MAX_ALLOC (1024 * 1024) +#define MIN_AVAIL 10 + +#define RANDOM_VALUE(x) ((random() % ((x) * 10)) / 10) + +/* pointer tracking structure */ +struct pnt_info_st { + long pi_crc; /* crc of storage */ + long pi_size; /* size of storage */ + void *pi_pnt; /* pnt to storage */ + struct pnt_info_st *pi_next; /* pnt to next */ +}; + +typedef struct pnt_info_st pnt_info_t; + +static pnt_info_t *pointer_grid; + +/* argument variables */ +static int best_fit_b = 0; /* set best fit flag */ +static int heavy_pack_b = 0; /* set heavy pack flg*/ +static int interactive_b = 0; /* interactive flag */ +static int log_trxn_b = 0; /* log mem trxns */ +static long max_alloc = MAX_ALLOC; /* amt of mem to use */ +static int max_pages_n = 0; /* max # pages */ +static int use_malloc_b = 0; /* use system alloc */ +static int max_pointers = MAX_POINTERS; /* # of pnts to use */ +static int no_free_b = 0; /* set no free flag */ +static long page_size = 0; /* mpool pagesize */ +static int use_sbrk_b = 0; /* use sbrk not mmap */ +static unsigned int seed_random = 0; /* random seed */ +static int default_iter_n = DEFAULT_ITERATIONS; /* # of iters */ +static int verbose_b = 0; /* verbose flag */ + +/* + * static long hex_to_long + * + * DESCRIPTION: + * + * Hexadecimal string to integer translation. + * + * RETURNS: + * + * Long value of converted hex string. + * + * ARGUMENTS: + * + * str -> Hex string we are converting. + */ +static long hex_to_long(const char *str) +{ + long ret; + const char *str_p = str; + + /* strip off spaces */ + for (; *str_p == ' ' || *str_p == '\t'; str_p++) { + } + + /* skip a leading 0[xX] */ + if (*str_p == '0' && (*(str_p + 1) == 'x' || *(str_p + 1) == 'X')) { + str_p += 2; + } + + for (ret = 0;; str_p++) { + if (*str_p >= '0' && *str_p <= '9') { + ret = ret * 16 + (*str_p - '0'); + } + else if (*str_p >= 'a' && *str_p <= 'f') { + ret = ret * 16 + (*str_p - 'a' + 10); + } + else if (*str_p >= 'A' && *str_p <= 'F') { + ret = ret * 16 + (*str_p - 'A' + 10); + } + else { + break; + } + } + + return ret; +} + +/* + * static void* get_address + * + * DESCRIPTION: + * + * Read an address from the user. + * + * RETURNS: + * + * Address read in from user. + * + * ARGUMENTS: + * + * None. + */ +static void *get_address(void) +{ + char line[80]; + void *pnt; + + do { + (void)printf("Enter a hex address: "); + if (fgets(line, sizeof(line), stdin) == NULL) { + return NULL; + } + } while (line[0] == '\0'); + + pnt = (void *)hex_to_long(line); + + return pnt; +} + +/* + * static void do_random + * + * DESCRIPTION: + * + * Try ITER_N random program iterations, returns 1 on success else 0 + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * pool <-> Out memory pool. + * + * iter_n -> Number of iterations to run. + */ +static void do_random(mpool_t *pool, const int iter_n) +{ + int iter_c, free_c, ret; + long max = max_alloc, amount; + char *chunk_p; + void *new_pnt; + pnt_info_t *free_p, *used_p = NULL; + pnt_info_t *pnt_p, *last_p; + + if (use_malloc_b) { + pointer_grid = (pnt_info_t *)malloc(sizeof(pnt_info_t) * max_pointers); + } + else { + pointer_grid = (pnt_info_t *)mpool_alloc(pool, + sizeof(pnt_info_t) * max_pointers, + &ret); + } + if (pointer_grid == NULL) { + (void)printf("mpool_t: problems allocating %d pointer slots: %s\n", + max_pointers, strerror(errno)); + return; + } + + /* initialize free list */ + free_p = pointer_grid; + for (pnt_p = pointer_grid; pnt_p < pointer_grid + max_pointers; pnt_p++) { + pnt_p->pi_size = 0; + pnt_p->pi_pnt = NULL; + pnt_p->pi_next = pnt_p + 1; + } + /* redo the last next pointer */ + (pnt_p - 1)->pi_next = NULL; + free_c = max_pointers; + + for (iter_c = 0; iter_c < iter_n;) { + int which; + + /* special case when doing non-linear stuff, sbrk took all memory */ + if (max < MIN_AVAIL && free_c == max_pointers) { + break; + } + + if (free_c < max_pointers && used_p == NULL) { + (void)fprintf(stderr, "mpool_t: problem with test program free list\n"); + exit(1); + } + + /* decide whether to malloc a new pointer or free/realloc an existing */ + which = RANDOM_VALUE(4); + + /* + * < MIN_AVAIL means alloc as long as we have enough memory and + * there are free slots we do an allocation, else we free + */ + if (free_c == max_pointers + || (free_c > 0 && which < 3 && max >= MIN_AVAIL)) { + + while (1) { + amount = RANDOM_VALUE(max / 2); + if (amount > 0) { + break; + } + } + which = RANDOM_VALUE(9); + pnt_p = NULL; + + switch (which) { + + case 0: case 1: case 2: + pnt_p = free_p; + if (use_malloc_b) { + pnt_p->pi_pnt = malloc(amount); + } + else { + pnt_p->pi_pnt = mpool_alloc(pool, amount, &ret); + } + + if (verbose_b) { + (void)printf("%d: malloc %ld (max %ld) into slot %d. got %#lx\n", + iter_c + 1, amount, max, pnt_p - pointer_grid, + (long)pnt_p->pi_pnt); + } + + if (pnt_p->pi_pnt == NULL) { + (void)printf("malloc of %ld failed: %s\n", + amount, + (use_malloc_b ? strerror(errno) : mpool_strerror(ret))); + } + pnt_p->pi_size = amount; + break; + + case 3: case 4: case 5: + pnt_p = free_p; + if (use_malloc_b) { + pnt_p->pi_pnt = calloc(amount, sizeof(char)); + } + else { + pnt_p->pi_pnt = mpool_calloc(pool, amount, sizeof(char), &ret); + } + + if (verbose_b) { + (void)printf("%d: calloc %ld (max %ld) into slot %d. got %#lx\n", + iter_c + 1, amount, max, pnt_p - pointer_grid, + (long)pnt_p->pi_pnt); + } + + /* test the returned block to make sure that is has been cleared */ + if (pnt_p->pi_pnt == NULL) { + (void)printf("calloc of %ld failed: %s\n", + amount, + (use_malloc_b ? strerror(errno) : mpool_strerror(ret))); + } + else { + for (chunk_p = pnt_p->pi_pnt; + chunk_p < (char *)pnt_p->pi_pnt + amount; + chunk_p++) { + if (*chunk_p != '\0') { + (void)printf("calloc of %ld not zeroed on iteration #%d\n", + amount, iter_c + 1); + break; + } + } + pnt_p->pi_size = amount; + } + break; + + case 6: case 7: case 8: + if (free_c == max_pointers) { + continue; + } + + which = RANDOM_VALUE(max_pointers - free_c); + for (pnt_p = used_p; which > 0; which--) { + pnt_p = pnt_p->pi_next; + } + + if (use_malloc_b) { + new_pnt = realloc(pnt_p->pi_pnt, amount); + } + else { + new_pnt = mpool_resize(pool, pnt_p->pi_pnt, amount, + &ret); + } + + if (verbose_b) { + (void)printf("%d: resize %#lx from %ld to %ld (max %ld) slot %d. " + "got %#lx\n", + iter_c + 1, (long)pnt_p->pi_pnt, pnt_p->pi_size, amount, + max, pnt_p - pointer_grid, (long)new_pnt); + } + + if (new_pnt == NULL) { + (void)printf("resize of %#lx old size %ld new size %ld failed: %s\n", + (long)pnt_p->pi_pnt, pnt_p->pi_size, amount, + (use_malloc_b ? strerror(errno) : mpool_strerror(ret))); + pnt_p->pi_pnt = NULL; + pnt_p->pi_size = 0; + } + else { + /* we effectively freed the old memory */ + max += pnt_p->pi_size; + pnt_p->pi_pnt = new_pnt; + pnt_p->pi_size = amount; + } + break; + + default: + break; + } + + if (pnt_p != NULL && pnt_p->pi_pnt != NULL) { + if (pnt_p == free_p) { + free_p = pnt_p->pi_next; + pnt_p->pi_next = used_p; + used_p = pnt_p; + free_c--; + } + + max -= amount; + iter_c++; + } + continue; + } + + /* + * choose a rand slot to free and make sure it is not a free-slot + */ + which = RANDOM_VALUE(max_pointers - free_c); + /* find pnt in the used list */ + last_p = NULL; + for (pnt_p = used_p, last_p = NULL; + pnt_p != NULL && which > 0; + last_p = pnt_p, pnt_p = pnt_p->pi_next, which--) { + } + if (pnt_p == NULL) { + /* huh? error here */ + abort(); + } + if (last_p == NULL) { + used_p = pnt_p->pi_next; + } + else { + last_p->pi_next = pnt_p->pi_next; + } + + if (use_malloc_b) { + free(pnt_p->pi_pnt); + } + else { + ret = mpool_free(pool, pnt_p->pi_pnt); + if (ret != MPOOL_ERROR_NONE) { + (void)printf("free error on pointer '%#lx' of size %ld: %s\n", + (long)pnt_p->pi_pnt, pnt_p->pi_size, + mpool_strerror(ret)); + } + } + + if (verbose_b) { + (void)printf("%d: free'd %ld bytes from slot %d (%#lx)\n", + iter_c + 1, pnt_p->pi_size, pnt_p - pointer_grid, + (long)pnt_p->pi_pnt); + } + + pnt_p->pi_pnt = NULL; + pnt_p->pi_next = free_p; + free_p = pnt_p; + free_c++; + + max += pnt_p->pi_size; + iter_c++; + } + + /* free used pointers */ + for (pnt_p = pointer_grid; pnt_p < pointer_grid + max_pointers; pnt_p++) { + if (pnt_p->pi_pnt != NULL) { + if (use_malloc_b) { + free(pnt_p->pi_pnt); + } + else { + ret = mpool_free(pool, pnt_p->pi_pnt); + if (ret != MPOOL_ERROR_NONE) { + (void)printf("free error on pointer '%#lx' of size %ld: %s\n", + (long)pnt_p->pi_pnt, pnt_p->pi_size, + mpool_strerror(ret)); + } + } + } + } + + if (use_malloc_b) { + free(pointer_grid); + } + else { + ret = mpool_free(pool, pointer_grid); + if (ret != MPOOL_ERROR_NONE) { + (void)printf("free error on grid pointer: %s\n", mpool_strerror(ret)); + } + } +} + +/* + * static void do_interactive + * + * DESCRIPTION: + * + * Run the interactive section of the program. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * pool <-> Out memory pool. + */ +static void do_interactive(mpool_t *pool) +{ + int len, ret; + char line[128], *line_p; + void *pnt, *new_pnt; + + (void)printf("Mpool test program. Type 'help' for assistance.\n"); + + for (;;) { + (void)printf("> "); + if (fgets(line, sizeof(line), stdin) == NULL) { + break; + } + line_p = strchr(line, '\n'); + if (line_p != NULL) { + *line_p = '\0'; + } + + len = strlen(line); + if (len == 0) { + continue; + } + + if (strncmp(line, "?", len) == 0 + || strncmp(line, "help", len) == 0) { + (void)printf("\thelp - print this message\n\n"); + + (void)printf("\tmalloc - allocate memory\n"); + (void)printf("\tcalloc - allocate/clear memory\n"); + (void)printf("\tresize - resize memory\n"); + (void)printf("\tfree - deallocate memory\n\n"); + + (void)printf("\tclear - clear the pool\n"); + (void)printf("\toverwrite - overwrite some memory to test errors\n"); + (void)printf("\trandom - randomly execute a number of [de] allocs\n"); + + (void)printf("\tquit - quit this test program\n"); + continue; + } + + if (strncmp(line, "quit", len) == 0) { + break; + } + + if (strncmp(line, "malloc", len) == 0) { + int size; + + (void)printf("How much to malloc: "); + if (fgets(line, sizeof(line), stdin) == NULL) { + break; + } + size = atoi(line); + pnt = mpool_alloc(pool, size, &ret); + if (pnt == NULL) { + (void)printf("malloc(%d) failed: %s\n", size, mpool_strerror(ret)); + } + else { + (void)printf("malloc(%d) returned '%#lx'\n", size, (long)pnt); + } + continue; + } + + if (strncmp(line, "calloc", len) == 0) { + int size; + + (void)printf("How much to calloc: "); + if (fgets(line, sizeof(line), stdin) == NULL) { + break; + } + size = atoi(line); + pnt = mpool_calloc(pool, size, sizeof(char), &ret); + if (pnt == NULL) { + (void)printf("calloc(%d) failed: %s\n", size, mpool_strerror(ret)); + } + else { + (void)printf("calloc(%d) returned '%#lx'\n", size, (long)pnt); + } + continue; + } + + if (strncmp(line, "resize", len) == 0) { + int size, old_size; + + pnt = get_address(); + + (void)printf("Old size of allocation: "); + if (fgets(line, sizeof(line), stdin) == NULL) { + break; + } + old_size = atoi(line); + (void)printf("New size of allocation: "); + if (fgets(line, sizeof(line), stdin) == NULL) { + break; + } + size = atoi(line); + + new_pnt = mpool_resize(pool, pnt, size, &ret); + if (new_pnt == NULL) { + (void)printf("resize(%#lx, %d) failed: %s\n", + (long)pnt, size, mpool_strerror(ret)); + } + else { + (void)printf("resize(%#lx, %d) returned '%#lx'\n", + (long)pnt, size, (long)new_pnt); + } + continue; + } + + if (strncmp(line, "free", len) == 0) { + int old_size; + + pnt = get_address(); + + (void)printf("Old minimum size we are freeing: "); + if (fgets(line, sizeof(line), stdin) == NULL) { + break; + } + old_size = atoi(line); + ret = mpool_free(pool, pnt); + if (ret != MPOOL_ERROR_NONE) { + (void)fprintf(stderr, "free failed: %s\n", mpool_strerror(ret)); + } + continue; + } + + if (strncmp(line, "clear", len) == 0) { + ret = mpool_clear(pool); + if (ret == MPOOL_ERROR_NONE) { + (void)fprintf(stderr, "clear succeeded\n"); + } + else { + (void)fprintf(stderr, "clear failed: %s\n", mpool_strerror(ret)); + } + continue; + } + + if (strncmp(line, "overwrite", len) == 0) { + char *overwrite = "OVERWRITTEN"; + + pnt = get_address(); + memcpy((char *)pnt, overwrite, strlen(overwrite)); + (void)printf("Done.\n"); + continue; + } + + /* do random heap hits */ + if (strncmp(line, "random", len) == 0) { + int iter_n; + + (void)printf("How many iterations[%d]: ", default_iter_n); + if (fgets(line, sizeof(line), stdin) == NULL) { + break; + } + if (line[0] == '\0' || line[0] == '\n') { + iter_n = default_iter_n; + } + else { + iter_n = atoi(line); + } + + do_random(pool, iter_n); + continue; + } + + (void)printf("Unknown command '%s'. Type 'help' for assistance.\n", line); + } +} + +/* + * static void log_func + * + * DESCRIPTION: + * + * Mpool transaction log function. + * + * RETURNS: + * + * None. + * + * ARGUMENT: + * + * mp_p -> Associated mpool address. + * + * func_id -> Integer function ID which identifies which mpool + * function is being called. + * + * byte_size -> Optionally specified byte size. + * + * ele_n -> Optionally specified element number. For mpool_calloc + * only. + * + * new_addr -> Optionally specified new address. For mpool_alloc, + * mpool_calloc, and mpool_resize only. + * + * old_addr -> Optionally specified old address. For mpool_resize and + * mpool_free only. + * + * old_byte_size -> Optionally specified old byte size. For + * mpool_resize only. + */ +static void log_func(const void *mp_p, const int func_id, + const unsigned long byte_size, + const unsigned long ele_n, + const void *new_addr, const void *old_addr, + const unsigned long old_byte_size) +{ + (void)printf("mp %#lx ", (long)mp_p); + + switch (func_id) { + + case MPOOL_FUNC_CLOSE: + (void)printf("close\n"); + break; + + case MPOOL_FUNC_CLEAR: + (void)printf("clear\n"); + break; + + case MPOOL_FUNC_ALLOC: + (void)printf("alloc %lu bytes got %#lx\n", + byte_size, (long)new_addr); + break; + + case MPOOL_FUNC_CALLOC: + (void)printf("calloc %lu ele size, %lu ele number, got %#lx\n", + byte_size, ele_n, (long)new_addr); + break; + + case MPOOL_FUNC_FREE: + (void)printf("free %#lx of %lu bytes\n", (long)old_addr, byte_size); + break; + + case MPOOL_FUNC_RESIZE: + (void)printf("resize %#lx of %lu bytes to %lu bytes, got %#lx\n", + (long)old_addr, old_byte_size, byte_size, + (long)new_addr); + break; + + default: + (void)printf("unknown function %d, %lu bytes\n", func_id, byte_size); + break; + } +} + +/* + * static void usage + * + * DESCRIPTION: + * + * Print a usage message. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * None. + */ +static void usage(void) +{ + (void)fprintf(stderr, + "Usage: mpool_t [-bhHilMnsv] [-m size] [-p number] " + "[-P size] [-S seed] [-t times]\n"); + (void)fprintf(stderr, + " -b set MPOOL_FLAG_BEST_FIT\n" + " -h set MPOOL_FLAG_NO_FREE\n" + " -H use system heap not mpool\n" + " -i turn on interactive mode\n" + " -l log memory transactions\n" + " -M max number pages in mpool\n" + " -n set MPOOL_FLAG_NO_FREE\n" + " -s use sbrk instead of mmap\n" + " -v enable verbose messages\n" + " -m size maximum allocation to test\n" + " -p max-pnts number of pointers to test\n" + " -S seed-rand seed for random function\n" + " -t interations number of iterations to run\n"); + exit(1); +} + +/* + * static void process_args + * + * DESCRIPTION: + * + * Process our arguments. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * None. + */ +static void process_args(int argc, char ** argv) +{ + argc--, argv++; + + /* process the args */ + for (; *argv != NULL; argv++, argc--) { + if (**argv != '-') { + continue; + } + + switch (*(*argv + 1)) { + + case 'b': + best_fit_b = 1; + break; + case 'h': + heavy_pack_b = 1; + break; + case 'H': + use_malloc_b = 1; + break; + case 'i': + interactive_b = 1; + break; + case 'l': + log_trxn_b = 1; + break; + case 'm': + argv++, argc--; + if (argc <= 0) { + usage(); + } + max_alloc = atoi(*argv); + break; + case 'M': + max_pages_n = 1; + break; + case 'n': + no_free_b = 1; + break; + case 'p': + argv++, argc--; + if (argc <= 0) { + usage(); + } + max_pointers = atoi(*argv); + break; + case 'P': + argv++, argc--; + if (argc <= 0) { + usage(); + } + page_size = atoi(*argv); + break; + case 'S': + argv++, argc--; + if (argc <= 0) { + usage(); + } + seed_random = atoi(*argv); + break; + case 't': + argv++, argc--; + if (argc <= 0) { + usage(); + } + default_iter_n = atoi(*argv); + break; + case 'v': + verbose_b = 1; + break; + default: + usage(); + break; + } + } +} + +/* + * Main routine + */ +int main(int argc, char **argv) +{ + int ret; + unsigned int flags = 0, pool_page_size; + unsigned long num_alloced, user_alloced, max_alloced, tot_alloced; + mpool_t *pool; + + process_args(argc, argv); + + /* repeat until we get a non 0 seed */ + while (seed_random == 0) { + seed_random = time(0) ^ getpid(); + } + (void)srandom(seed_random); + + (void)printf("Random seed is %u\n", seed_random); + + if (best_fit_b) { + flags |= MPOOL_FLAG_BEST_FIT; + } + if (heavy_pack_b) { + flags |= MPOOL_FLAG_HEAVY_PACKING; + } + if (no_free_b) { + flags |= MPOOL_FLAG_NO_FREE; + } + if (use_sbrk_b) { + flags |= MPOOL_FLAG_USE_SBRK; + } + + /* open our memory pool */ + pool = mpool_open(flags, page_size, NULL, &ret); + if (pool == NULL) { + (void)fprintf(stderr, "Error in mpool_open: %s\n", mpool_strerror(ret)); + exit(1); + } + + /* are we logging transactions */ + if (log_trxn_b) { + ret = mpool_set_log_func(pool, log_func); + if (ret != MPOOL_ERROR_NONE) { + (void)fprintf(stderr, "Error in mpool_set_log_func: %s\n", + mpool_strerror(ret)); + } + } + + if (max_pages_n > 0) { + ret = mpool_set_max_pages(pool, max_pages_n); + if (ret != MPOOL_ERROR_NONE) { + (void)fprintf(stderr, "Error in mpool_set_max_pages: %s\n", + mpool_strerror(ret)); + } + } + + if (interactive_b) { + do_interactive(pool); + } + else { + (void)printf("Running %d tests (use -i for interactive)...\n", + default_iter_n); + (void)fflush(stdout); + + do_random(pool, default_iter_n); + } + + /* get stats from the pool */ + ret = mpool_stats(pool, &pool_page_size, &num_alloced, &user_alloced, + &max_alloced, &tot_alloced); + if (ret == MPOOL_ERROR_NONE) { + (void)printf("Pool page size = %d. Number active allocated = %lu\n", + pool_page_size, num_alloced); + (void)printf("User bytes allocated = %lu. Max space allocated = %lu\n", + user_alloced, max_alloced); + (void)printf("Total space allocated = %lu\n", tot_alloced); + } + else { + (void)fprintf(stderr, "Error in mpool_stats: %s\n", mpool_strerror(ret)); + } + + /* close the pool */ + ret = mpool_close(pool); + if (ret != MPOOL_ERROR_NONE) { + (void)fprintf(stderr, "Error in mpool_close: %s\n", mpool_strerror(ret)); + exit(1); + } + + exit(0); +} diff --git a/libclamav/phishcheck.c b/libclamav/phishcheck.c index ab6893580..d7bef7449 100644 --- a/libclamav/phishcheck.c +++ b/libclamav/phishcheck.c @@ -52,6 +52,10 @@ #include "md5.h" #include +#ifdef USE_MPOOL +#include "mpool.h" +#endif + #define DOMAIN_REAL 1 #define DOMAIN_DISPLAY 0 @@ -857,7 +861,11 @@ int phishing_init(struct cl_engine* engine) { struct phishcheck* pchk; if(!engine->phishcheck) { +#ifdef USE_MPOOL + pchk = engine->phishcheck = mpool_alloc(engine->mempool, sizeof(struct phishcheck), NULL); +#else pchk = engine->phishcheck = cli_malloc(sizeof(struct phishcheck)); +#endif if(!pchk) return CL_EMEM; pchk->is_disabled=1; @@ -875,7 +883,11 @@ int phishing_init(struct cl_engine* engine) cli_dbgmsg("Initializing phishcheck module\n"); if(build_regex(&pchk->preg_numeric,numeric_url_regex,1)) { +#ifdef USE_MPOOL + mpool_free(engine->mempool, pchk); +#else free(pchk); +#endif engine->phishcheck = NULL; return CL_EFORMAT; } diff --git a/libclamav/readdb.c b/libclamav/readdb.c index da026d539..2c47ec5b9 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -67,6 +67,10 @@ #include #endif +#ifdef USE_MPOOL +#include "mpool.h" +#endif + #ifdef CL_THREAD_SAFE # include static pthread_mutex_t cli_ref_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -339,14 +343,27 @@ int cli_initengine(struct cl_engine **engine, unsigned int options) (*engine)->refcount = 1; +#ifdef USE_MPOOL + if(!((*engine)->mempool = mpool_open(MPOOL_FLAG_BEST_FIT, 0, NULL, NULL))) { + cli_errmsg("Can't allocate memory for memory pool!\n"); + return CL_EMEM; + } + + (*engine)->root = mpool_calloc((*engine)->mempool, CLI_MTARGETS, sizeof(struct cli_matcher *), NULL); +#else (*engine)->root = cli_calloc(CLI_MTARGETS, sizeof(struct cli_matcher *)); +#endif if(!(*engine)->root) { /* no need to free previously allocated memory here */ cli_errmsg("Can't allocate memory for roots!\n"); return CL_EMEM; } +#ifdef USE_MPOOL + (*engine)->dconf = cli_dconf_init((*engine)->mempool); +#else (*engine)->dconf = cli_dconf_init(); +#endif if(!(*engine)->dconf) { cli_errmsg("Can't initialize dynamic configuration\n"); return CL_EMEM; @@ -369,7 +386,12 @@ static int cli_initroots(struct cl_engine *engine, unsigned int options) for(i = 0; i < CLI_MTARGETS; i++) { if(!engine->root[i]) { cli_dbgmsg("Initializing engine->root[%d]\n", i); +#ifdef USE_MPOOL + root = engine->root[i] = (struct cli_matcher *) cli_calloc(engine->mempool, 1, sizeof(struct cli_matcher), NULL); + root->mempool = engine->mempool; +#else root = engine->root[i] = (struct cli_matcher *) cli_calloc(1, sizeof(struct cli_matcher)); +#endif if(!root) { cli_errmsg("cli_initroots: Can't allocate memory for cli_matcher\n"); return CL_EMEM; From b583d6ed275cc5cce796ec38172fe4797aed0acd Mon Sep 17 00:00:00 2001 From: aCaB Date: Fri, 17 Oct 2008 20:33:15 +0000 Subject: [PATCH 03/21] small update git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4267 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/TODO | 12 +++++++++ libclamav/matcher-ac.c | 9 +++---- libclamav/readdb.c | 61 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 libclamav/TODO diff --git a/libclamav/TODO b/libclamav/TODO new file mode 100644 index 000000000..6209138f5 --- /dev/null +++ b/libclamav/TODO @@ -0,0 +1,12 @@ +TBD +- engine->root[x]->ac_lsigtable and childreen +- engine->md5_hdb +- engine->md5_mdb + soff + md5_sizes +- engine->md5_fp +- engine->zip_mlist +- engine->rar_mlist +- engine->phishcheck and friends (free only?) +- engine->pua_cats +- engine->ftypes +- engine->ignored + diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c index ff021600d..5abfbfe58 100644 --- a/libclamav/matcher-ac.c +++ b/libclamav/matcher-ac.c @@ -1536,6 +1536,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex unsigned int mpoolvirnamesz = strlen(mpoolvirname) + 1; if((new->virname = mpool_alloc(root->mempool, mpoolvirnamesz, NULL)) != NULL) memcpy(new->virname, mpoolvirname, mpoolvirnamesz); + free(mpoolvirname); } else new->virname = NULL; } #else @@ -1559,12 +1560,8 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(offset) { #ifdef USE_MPOOL - char *mpooloffset = cli_strdup(offset); - if(mpooloffset) { - unsigned int mpooloffsetsz = strlen(mpooloffset) + 1; - if((new->offset = mpool_alloc(root->mempool, mpooloffsetsz, NULL))) - memcpy(new->offset, mpooloffset, mpooloffsetsz); - } else new->offset = NULL; + if((new->offset = mpool_alloc(root->mempool, strlen(mpooloffset) + 1, NULL))) + strcpy(new->offset, offset); #else new->offset = cli_strdup(offset); #endif diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 2c47ec5b9..a15b1c8a1 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -283,29 +283,78 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex } } else { +#ifdef USE_MPOOL + bm_new = (struct cli_bm_patt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_bm_patt)); +#else bm_new = (struct cli_bm_patt *) cli_calloc(1, sizeof(struct cli_bm_patt)); +#endif if(!bm_new) return CL_EMEM; - if(!(bm_new->pattern = (unsigned char *) cli_hex2str(hexsig))) { +#ifdef USE_MPOOL +{ + unsigned char *mpoolhexsig = (unsigned char *) cli_hex2str(hexsig); + if(mpoolhexsig) { + unsigned int mpoolhexsigsz = strlen(hexsig) / 2 + 1; + if((bm_new->pattern = mpool_alloc(root->mempool, mpoolhexsigsz, NULL))) + memcpy(bm_new->pattern, mpoolhexsig, mpoolhexsigsz); + free(mpoolhexsig); + } else bm_new->pattern = NULL; +} +#else + bm_new->pattern = (unsigned char *) cli_hex2str(hexsig) +#end + if(!bm_new->pattern) { +#ifdef USE_MPOOL + mpool_free(root->mempool, bm_new); +#else free(bm_new); +#endif return CL_EMALFDB; } bm_new->length = strlen(hexsig) / 2; +#ifdef USE_MPOOL +{ + char *mpoolvirname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); + if(mpoolvirname) { + unsigned int mpoolvirnamesz = strlen(mpoolvirname) + 1; + if((bm_new->virname = mpool_alloc(root->mempool, mpoolvirnamesz, NULL))) + memcpy(bm_new->virname, mpoolvirname, mpoolvirname); + free(mpoolvirname); + } else bm_new->virname = NULL; +} +#else bm_new->virname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); +#end if(!bm_new->virname) { +#ifdef USE_MPOOL + mpool_free(root->mempool, bm_new->pattern); + mpool_free(root->mempool, bm_new); +#else free(bm_new->pattern); free(bm_new); +#endif return CL_EMEM; } if(offset) { +#ifdef USE_MPOOL + if((bm_new->offset = mpool_alloc(root->mempool, streln(offset) + 1, NULL))) + strcpy(bm_new->offset, offset); +#else bm_new->offset = cli_strdup(offset); +#endif if(!bm_new->offset) { +#ifdef USE_MPOOL + mpool_free(root->mempool, bm_new->pattern); + mpool_free(root->mempool, bm_new->virname); + mpool_free(root->mempool, bm_new); +#else free(bm_new->pattern); free(bm_new->virname); free(bm_new); +#endif return CL_EMEM; } } @@ -317,9 +366,15 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex if((ret = cli_bm_addpatt(root, bm_new))) { cli_errmsg("cli_parse_add(): Problem adding signature (4).\n"); +#ifdef USE_MPOOL + mpool_free(root->mempool, bm_new->pattern); + mpool_free(root->mempool, bm_new->virname); + mpool_free(root->mempool, bm_new); +#else free(bm_new->pattern); free(bm_new->virname); free(bm_new); +#endif return ret; } } @@ -2147,6 +2202,9 @@ void cl_free(struct cl_engine *engine) pthread_mutex_unlock(&cli_ref_mutex); #endif +#ifdef USE_MPOOL + if(engine->mempool) mpool_close(engine->mempool); +#else if(engine->root) { for(i = 0; i < CLI_MTARGETS; i++) { if((root = engine->root[i])) { @@ -2217,6 +2275,7 @@ void cl_free(struct cl_engine *engine) cli_ftfree(engine->ftypes); cli_freeign(engine); +#endif /* USE_MPOOL */ free(engine); } From 0728972ea506b43bb0e1c335e48b3a49a6cf187f Mon Sep 17 00:00:00 2001 From: aCaB Date: Sat, 18 Oct 2008 00:16:23 +0000 Subject: [PATCH 04/21] (hoepfully) completed db load, regexes and hashes missing need to recheck strlen(hex2string) bugs, need to figure how to hangle regexes and hashes: edwiiiiiiin!!! :D git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4268 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/TODO | 4 +- libclamav/hashtab.c | 12 ++ libclamav/hashtab.h | 9 ++ libclamav/matcher-ac.c | 2 +- libclamav/matcher.h | 4 +- libclamav/phish_whitelist.c | 9 ++ libclamav/readdb.c | 293 +++++++++++++++++++++++++++++++++--- libclamav/regex_list.c | 20 ++- libclamav/regex_list.h | 7 + 9 files changed, 338 insertions(+), 22 deletions(-) diff --git a/libclamav/TODO b/libclamav/TODO index 6209138f5..799d738e5 100644 --- a/libclamav/TODO +++ b/libclamav/TODO @@ -1,6 +1,5 @@ TBD - engine->root[x]->ac_lsigtable and childreen -- engine->md5_hdb - engine->md5_mdb + soff + md5_sizes - engine->md5_fp - engine->zip_mlist @@ -10,3 +9,6 @@ TBD - engine->ftypes - engine->ignored +- pchk->preg_numeric ?? +- load_regex_matcher +- hashset_init / hashset_addkey / ?? \ No newline at end of file diff --git a/libclamav/hashtab.c b/libclamav/hashtab.c index 3747fc839..5b1ce9c32 100644 --- a/libclamav/hashtab.c +++ b/libclamav/hashtab.c @@ -30,6 +30,10 @@ #include "others.h" #include "hashtab.h" +#ifdef USE_MPOOL +#include "mpool.h" +#endif + #define MODULE_NAME "hashtab: " static const char DELETED_KEY[] = ""; @@ -168,7 +172,11 @@ static inline void PROFILE_REPORT(const struct hashtable *s) #define PROFILE_REPORT(s) #endif +#ifdef USE_MPOOL +int hashtab_init(struct hashtable *s,size_t capacity, mpool_t *mempool) +#else int hashtab_init(struct hashtable *s,size_t capacity) +#endif { if(!s) return CL_ENULLARG; @@ -176,7 +184,11 @@ int hashtab_init(struct hashtable *s,size_t capacity) PROFILE_INIT(s); capacity = nearest_power(capacity); +#ifdef USE_MPOOL + s->htable = mpool_calloc(mempool, capacity,sizeof(*s->htable), NULL); +#else s->htable = cli_calloc(capacity,sizeof(*s->htable)); +#endif if(!s->htable) return CL_EMEM; s->capacity = capacity; diff --git a/libclamav/hashtab.h b/libclamav/hashtab.h index 98876bd2b..90a594e8f 100644 --- a/libclamav/hashtab.h +++ b/libclamav/hashtab.h @@ -25,6 +25,11 @@ #include #include #include "cltypes.h" + +#ifdef USE_MPOOL +#include "mpool.h" +#endif + typedef long element_data; /* define this for debugging/profiling purposes only, NOT in production/release code */ @@ -78,7 +83,11 @@ struct hashtable { int hashtab_generate_c(const struct hashtable *s,const char* name); struct element* hashtab_find(const struct hashtable *s, const char* key, const size_t len); +#ifdef USE_MPOOL +int hashtab_init(struct hashtable *s,size_t capacity, mpool_t *mempool); +#else int hashtab_init(struct hashtable *s,size_t capacity); +#endif const struct element* hashtab_insert(struct hashtable *s, const char* key, const size_t len, const element_data data); void hashtab_delete(struct hashtable *s,const char* key,const size_t len); void hashtab_clear(struct hashtable *s); diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c index 5abfbfe58..cdb50d0a5 100644 --- a/libclamav/matcher-ac.c +++ b/libclamav/matcher-ac.c @@ -1445,7 +1445,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex } else new->pattern = NULL; } #else - new->pattern = cli_hex2ui(hex ? hex : hexsig) + new->pattern = cli_hex2ui(hex ? hex : hexsig); #endif if(new->pattern == NULL) { diff --git a/libclamav/matcher.h b/libclamav/matcher.h index cd7fd69d0..0f2762c6b 100644 --- a/libclamav/matcher.h +++ b/libclamav/matcher.h @@ -85,7 +85,9 @@ struct cli_matcher { uint16_t maxpatlen; uint8_t ac_only; - mpool_t mempool; +#ifdef USE_MPOOL + mpool_t *mempool; +#endif }; struct cli_meta_node { diff --git a/libclamav/phish_whitelist.c b/libclamav/phish_whitelist.c index 55fd2fd52..12c13753c 100644 --- a/libclamav/phish_whitelist.c +++ b/libclamav/phish_whitelist.c @@ -45,6 +45,10 @@ #include "phish_whitelist.h" #include "regex_list.h" +#ifdef USE_MPOOL +#include "mpool.h" +#endif + int whitelist_match(const struct cl_engine* engine,char* real_url,const char* display_url,int hostOnly) { const char* info;/*unused*/ @@ -55,7 +59,12 @@ int whitelist_match(const struct cl_engine* engine,char* real_url,const char* di int init_whitelist(struct cl_engine* engine) { if(engine) { +#ifdef USE_MPOOL + engine->whitelist_matcher = (struct regex_matcher *) mpool_malloc(engine->mempool, sizeof(struct regex_matcher), NULL); + engine->whitelist_matcher->mempool = engine->mempool; +#else engine->whitelist_matcher = (struct regex_matcher *) cli_malloc(sizeof(struct regex_matcher)); +#endif if(!engine->whitelist_matcher) return CL_EMEM; return init_regex_list(engine->whitelist_matcher); diff --git a/libclamav/readdb.c b/libclamav/readdb.c index a15b1c8a1..bfc56d574 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -302,8 +302,8 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex } else bm_new->pattern = NULL; } #else - bm_new->pattern = (unsigned char *) cli_hex2str(hexsig) -#end + bm_new->pattern = (unsigned char *) cli_hex2str(hexsig); +#endif if(!bm_new->pattern) { #ifdef USE_MPOOL mpool_free(root->mempool, bm_new); @@ -326,7 +326,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex } #else bm_new->virname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); -#end +#endif if(!bm_new->virname) { #ifdef USE_MPOOL mpool_free(root->mempool, bm_new->pattern); @@ -1064,20 +1064,32 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, } root = (*engine)->root[tdb.target[0]]; - +#ifdef USE_MPOOL + lsig = (struct cli_ac_lsig *) mpool_calloc((*engine)->mempool, 1, sizeof(struct cli_ac_lsig), NULL); +#else lsig = (struct cli_ac_lsig *) cli_calloc(1, sizeof(struct cli_ac_lsig)); +#endif if(!lsig) { cli_errmsg("cli_loadldb: Can't allocate memory for lsig\n"); FREE_TDB(tdb); ret = CL_EMEM; break; } +#ifdef USE_MPOOL + if((lsig->logic = mpool_alloc((*engine)->mempool, strlen(logic)+1, NULL))) + strcpy(lsig->logic, logic); +#else lsig->logic = cli_strdup(logic); +#endif if(!lsig->logic) { cli_errmsg("cli_loadldb: Can't allocate memory for lsig->logic\n"); FREE_TDB(tdb); ret = CL_EMEM; +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, lsig); +#else free(lsig); +#endif break; } @@ -1085,12 +1097,20 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, memcpy(&lsig->tdb, &tdb, sizeof(tdb)); root->ac_lsigs++; +#ifdef USE_MPOOL + newtable = (struct cli_ac_lsig **) mpool_realloc((*engine)->mempool, root->ac_lsigtable, root->ac_lsigs * sizeof(struct cli_ac_lsig *)); +#else newtable = (struct cli_ac_lsig **) cli_realloc(root->ac_lsigtable, root->ac_lsigs * sizeof(struct cli_ac_lsig *)); +#endif if(!newtable) { root->ac_lsigs--; cli_errmsg("cli_loadldb: Can't realloc root->ac_lsigtable\n"); FREE_TDB(tdb); +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, lsig); +#else free(lsig); +#endif ret = CL_EMEM; break; } @@ -1215,25 +1235,60 @@ static int cli_loadftm(FILE *fs, struct cl_engine **engine, unsigned int options break; } else if(atoi(tokens[0]) == 0) { /* memcmp() */ +#ifdef USE_MPOOL + new = (struct cli_ftype *) mpool_alloc((*engine)->mempool, sizeof(struct cli_ftype), NULL); +#else new = (struct cli_ftype *) cli_malloc(sizeof(struct cli_ftype)); +#endif if(!new) { ret = CL_EMEM; break; } new->type = type; new->offset = atoi(tokens[1]); +#ifdef USE_MPOOL +{ + unsigned char *mpoolmagic = cli_hex2str(tokens[2]); + if(mpoolmagic) { + if((new->magic = mpool_alloc((*engine)->mempool, strlen(mpoolmagic) + 1, NULL))) + strcpy(new->magic, mpoolmagic); + free(mpoolmagic); + } else new->magic = NULL; +} +#else new->magic = (unsigned char *) cli_hex2str(tokens[2]); +#endif if(!new->magic) { cli_errmsg("cli_loadftm: Can't decode the hex string\n"); ret = CL_EMALFDB; +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new); +#else free(new); +#endif break; } new->length = strlen(tokens[2]) / 2; +#ifdef USE_MPOOL +{ + unsigned char *mpooltname = cli_hex2str(tokens[3]); + if(mpooltname) { + if((new->tname = mpool_alloc((*engine)->mempool, strlen(mpooltname) + 1, NULL))) + strcpy(new->tname, mpooltname); + free(mpooltname); + } else new->tname = NULL; +} +#else new->tname = cli_strdup(tokens[3]); +#endif if(!new->tname) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->magic); + mpool_free((*engine)->mempool, new); +#else free(new->magic); free(new); +#endif ret = CL_EMEM; break; } @@ -1288,22 +1343,46 @@ static int cli_loadign(FILE *fs, struct cl_engine **engine, unsigned int options while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) { line++; cli_chomp(buffer); - +#ifdef USE_MPOOL + new = (struct cli_ignsig *) mpool_calloc((*engine)->mempool, 1, sizeof(struct cli_ignsig), NULL); +#else new = (struct cli_ignsig *) cli_calloc(1, sizeof(struct cli_ignsig)); +#endif if(!new) { ret = CL_EMEM; break; } - if(!(new->dbname = cli_strtok(buffer, 0, ":"))) { +#ifdef USE_MPOOL +{ + unsigned char *mpooldbname = cli_strtok(buffer, 0, ":"); + if(mpooldbname) { + if((new->dbname = mpool_alloc((*engine)->mempool, strlen(mpooldbname) + 1, NULL))) + strcpy(new->dbname, mpooldbname); + free(mpooldbname); + } else new->dbname = NULL; +} +#else + new->dbname = cli_strtok(buffer, 0, ":"); +#endif + if(!new->dbname) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new); +#else free(new); +#endif ret = CL_EMALFDB; break; } if(!(pt = cli_strtok(buffer, 1, ":"))) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->dbname); + mpool_free((*engine)->mempool, new); +#else free(new->dbname); free(new); +#endif ret = CL_EMALFDB; break; } else { @@ -1314,9 +1393,26 @@ static int cli_loadign(FILE *fs, struct cl_engine **engine, unsigned int options if((ret = hashset_addkey(&ignored->hs, new->line))) break; - if(!(new->signame = cli_strtok(buffer, 2, ":"))) { +#ifdef USE_MPOOL +{ + unsigned char *mpoolsigname = cli_strtok(buffer, 2, ":"); + if(mpoolsigname) { + if((new->signame = mpool_alloc((*engine)->mempool, strlen(mpoolsigname) + 1, NULL))) + strcpy(new->signame, mpoolsigname); + free(mpoolsigname); + } else new->signame = NULL; +} +#else + new->signame = cli_strtok(buffer, 2, ":"); +#endif + if(!new->signame) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->dbname); + mpool_free((*engine)->mempool, new); +#else free(new->dbname); free(new); +#endif ret = CL_EMALFDB; break; } @@ -1373,16 +1469,30 @@ static int cli_md5db_init(struct cl_engine **engine, unsigned int mode) if(mode == MD5_HDB) { +#ifdef USE_MPOOL + bm = (*engine)->md5_hdb = (struct cli_matcher *) mpool_calloc((*engine)->mempool, sizeof(struct cli_matcher), 1, NULL); +#else bm = (*engine)->md5_hdb = (struct cli_matcher *) cli_calloc(sizeof(struct cli_matcher), 1); +#endif } else if(mode == MD5_MDB) { +#ifdef USE_MPOOL + bm = (*engine)->md5_mdb = (struct cli_matcher *) mpool_calloc((*engine)->mempool, sizeof(struct cli_matcher), 1, NULL); +#else bm = (*engine)->md5_mdb = (struct cli_matcher *) cli_calloc(sizeof(struct cli_matcher), 1); +#endif } else { +#ifdef USE_MPOOL + bm = (*engine)->md5_fp = (struct cli_matcher *) mpool_calloc((*engine)->mempool, sizeof(struct cli_matcher), 1, NULL); +#else bm = (*engine)->md5_fp = (struct cli_matcher *) cli_calloc(sizeof(struct cli_matcher), 1); +#endif } if(!bm) return CL_EMEM; - +#ifdef USE_MPOOL + bm->mempool = (*engine)->mempool; +#endif if((ret = cli_bm_init(bm))) { cli_errmsg("cli_md5db_init: Failed to initialize B-M\n"); return ret; @@ -1438,47 +1548,100 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, if((*engine)->ignored && cli_chkign((*engine)->ignored, dbname, line, pt)) continue; - +#ifdef USE_MPOOL + new = (struct cli_bm_patt *) mpool_calloc((*engine)->mempool, 1, sizeof(struct cli_bm_patt), NULL); +#else new = (struct cli_bm_patt *) cli_calloc(1, sizeof(struct cli_bm_patt)); +#endif if(!new) { ret = CL_EMEM; break; } if(!(pt = tokens[md5_field])) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new); +#else free(new); +#endif ret = CL_EMALFDB; break; } +#ifdef USE_MPOOL + if(strlen(pt) == 32) { + unsigned char *mpoolhex = (unsigned char *) cli_hex2str(pt); + if(mpoolhex) { + if((new->pattern = mpool_alloc((*engine)->mempool, 17, NULL))) + memcpy(new->pattern, mpoolhex, 17); + free(mpoolhex); + } else new->pattern = NULL; + } else new->pattern = NULL; + if(new->pattern == NULL) { + cli_errmsg("cli_loadmd5: Malformed MD5 string at line %u\n", line); + mpool_free((*engine)->mempool, new); + ret = CL_EMALFDB; + break; + } +#else if(strlen(pt) != 32 || !(new->pattern = (unsigned char *) cli_hex2str(pt))) { cli_errmsg("cli_loadmd5: Malformed MD5 string at line %u\n", line); free(new); ret = CL_EMALFDB; break; } +#endif new->length = 16; if(!(pt = tokens[size_field])) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->pattern); + mpool_free((*engine)->mempool, new); +#else free(new->pattern); free(new); +#endif ret = CL_EMALFDB; break; } size = atoi(pt); - if(!(new->virname = cli_virname((char *) tokens[2], options & CL_DB_OFFICIAL, 0))) { +#ifdef USE_MPOOL + { + char *mpoolvname = cli_virname((char *) tokens[2], options & CL_DB_OFFICIAL, 0); + if(mpoolvname) { + if((new->virname = mpool_alloc((*engine)->mempool, strlen(mpoolvname) + 1, NULL))) + strcpy(new->virname, mpoolvname); + free(mpoolvname); + } else new->virname = NULL; + } +#else + new->virname = cli_virname((char *) tokens[2], options & CL_DB_OFFICIAL, 0); +#endif + if(!new->virname) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->pattern); + mpool_free((*engine)->mempool, new); +#else free(new->pattern); free(new); +#endif ret = CL_EMALFDB; break; } MD5_DB; if(!db && (ret = cli_md5db_init(engine, mode))) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->pattern); + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else + free(new->pattern); free(new->virname); free(new); +#endif break; } else { MD5_DB; @@ -1486,9 +1649,16 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, if((ret = cli_bm_addpatt(db, new))) { cli_errmsg("cli_loadmd5: Error adding BM pattern\n"); +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->pattern); + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else + free(new->pattern); free(new->virname); free(new); +#endif break; } @@ -1540,27 +1710,57 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, cli_chomp(buffer); +#ifdef USE_MPOOL + new = (struct cli_meta_node *) mpool_calloc((*engine)->mempool, 1, sizeof(struct cli_meta_node)); +#else new = (struct cli_meta_node *) cli_calloc(1, sizeof(struct cli_meta_node)); +#endif if(!new) { ret = CL_EMEM; break; } - if(!(new->virname = cli_virname(cli_strtok(buffer, 0, ":"), options & CL_DB_OFFICIAL, 1))) { +#ifdef USE_MPOOL + { + char *mpoolvname = cli_virname(cli_strtok(buffer, 0, ":"), options & CL_DB_OFFICIAL, 1); + if(mpoolvname) { + if((new->virname = mpool_alloc((*engine)->mempool, strlen(mpoolvname) + 1, NULL))) + strcpy(new->virname, mpoolvname); + free(mpoolvname); + } else new->virname = NULL; + } +#else + new->virname = cli_virname(cli_strtok(buffer, 0, ":"), options & CL_DB_OFFICIAL, 1); +#endif + if(!new->virname) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new); +#else free(new); +#endif ret = CL_EMEM; break; } if((*engine)->ignored && cli_chkign((*engine)->ignored, dbname, line, new->virname)) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else free(new->virname); free(new); +#endif continue; } if(!(pt = cli_strtok(buffer, 1, ":"))) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else free(new->virname); free(new); +#endif ret = CL_EMALFDB; break; } else { @@ -1568,22 +1768,49 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, free(pt); } - if(!(new->filename = cli_strtok(buffer, 2, ":"))) { +#ifdef USE_MPOOL + { + char *mpoolfname = cli_strtok(buffer, 2, ":"); + if(mpoolfname) { + if((new->filename = mpool_alloc((*engine)->mempool, strlen(mpoolfname) + 1, NULL))) + strcpy(new->filename, mpoolfname); + free(mpoolfname); + } else new->filename = NULL; + } +#else + new->filename = cli_strtok(buffer, 2, ":"); +#endif + if(!new->filename) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else free(new->virname); free(new); +#endif ret = CL_EMALFDB; break; } else { if(!strcmp(new->filename, "*")) { +#ifdef USE_MPOOL + mpool_free((*engine)->mempool, new->filename); +#else free(new->filename); +#endif new->filename = NULL; } } if(!(pt = cli_strtok(buffer, 3, ":"))) { - free(new->filename); +#ifdef USE_MPOOL + if(new->filename) mpool_free((*engine)->mempool, new->filename); + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else + if(new->filename) free(new->filename); free(new->virname); free(new); +#endif ret = CL_EMALFDB; break; } else { @@ -1595,9 +1822,15 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, } if(!(pt = cli_strtok(buffer, 4, ":"))) { - free(new->filename); +#ifdef USE_MPOOL + if(new->filename) mpool_free((*engine)->mempool, new->filename); + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else + if(new->filename) free(new->filename); free(new->virname); free(new); +#endif ret = CL_EMALFDB; break; } else { @@ -1609,9 +1842,15 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, } if(!(pt = cli_strtok(buffer, 5, ":"))) { - free(new->filename); +#ifdef USE_MPOOL + if(new->filename) mpool_free((*engine)->mempool, new->filename); + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else + if(new->filename) free(new->filename); free(new->virname); free(new); +#endif ret = CL_EMALFDB; break; } else { @@ -1629,9 +1868,15 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, } if(!(pt = cli_strtok(buffer, 6, ":"))) { - free(new->filename); +#ifdef USE_MPOOL + if(new->filename) mpool_free((*engine)->mempool, new->filename); + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else + if(new->filename) free(new->filename); free(new->virname); free(new); +#endif ret = CL_EMALFDB; break; } else { @@ -1643,9 +1888,15 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, } if(!(pt = cli_strtok(buffer, 7, ":"))) { - free(new->filename); +#ifdef USE_MPOOL + if(new->filename) mpool_free((*engine)->mempool, new->filename); + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else + if(new->filename) free(new->filename); free(new->virname); free(new); +#endif ret = CL_EMALFDB; break; } else { @@ -1657,9 +1908,15 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, } if(!(pt = cli_strtok(buffer, 8, ":"))) { - free(new->filename); +#ifdef USE_MPOOL + if(new->filename) mpool_free((*engine)->mempool, new->filename); + mpool_free((*engine)->mempool, new->virname); + mpool_free((*engine)->mempool, new); +#else + if(new->filename) free(new->filename); free(new->virname); free(new); +#endif ret = CL_EMALFDB; break; } else { diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c index 9c7b5433a..e98390996 100644 --- a/libclamav/regex_list.c +++ b/libclamav/regex_list.c @@ -57,6 +57,11 @@ #include "readdb.h" #include "jsparse/textbuf.h" #include "regex_suffix.h" + +#ifdef USE_MPOOL +#include "mpool.h" +#endif + /* Prototypes */ static regex_t *new_preg(struct regex_matcher *matcher); static size_t reverse_string(char *pattern); @@ -350,8 +355,13 @@ int init_regex_list(struct regex_matcher* matcher) matcher->list_inited=1; matcher->list_built=0; matcher->list_loaded=0; - +#ifdef USE_MPOOL + hashtab_init(&matcher->suffix_hash, 10, matcher->mempool); + matcher->suffixes->mempool = matcher->mempool; + matcher->md5_hashes->mempool = matcher->mempool; +#else hashtab_init(&matcher->suffix_hash, 10); +#endif if((rc = cli_ac_init(&matcher->suffixes, 2, 32))) { return rc; } @@ -704,10 +714,18 @@ static size_t reverse_string(char *pattern) static regex_t *new_preg(struct regex_matcher *matcher) { regex_t *r; +#ifdef USE_MPOOL + matcher->all_pregs = mpool_realloc(matcher->mempool, matcher->all_pregs, ++matcher->regex_cnt * sizeof(*matcher->all_pregs), NULL); +#else matcher->all_pregs = cli_realloc(matcher->all_pregs, ++matcher->regex_cnt * sizeof(*matcher->all_pregs)); +#endif if(!matcher->all_pregs) return NULL; +#ifdef USE_MPOOL + r = mpool_alloc(matcher->mempool, sizeof(*r), NULL); +#else r = cli_malloc(sizeof(*r)); +#endif if(!r) return NULL; matcher->all_pregs[matcher->regex_cnt-1] = r; diff --git a/libclamav/regex_list.h b/libclamav/regex_list.h index d0a34321a..c453b5936 100644 --- a/libclamav/regex_list.h +++ b/libclamav/regex_list.h @@ -29,6 +29,10 @@ #include "matcher.h" #include /* for gzFile */ +#ifdef USE_MPOOL +#include "mpool.h" +#endif + struct filter { uint32_t B[65536]; uint32_t end_fast[256]; @@ -51,6 +55,9 @@ struct regex_matcher { struct cli_matcher md5_hashes; struct filter md5_filter; struct filter filter; +#ifdef USE_MPOOL + mpool_t *mempool; +#endif int list_inited:2; int list_loaded:2; int list_built:2; From 885c2bf5b9480eb7082261c6b22912eeb4bbc44b Mon Sep 17 00:00:00 2001 From: aCaB Date: Sat, 18 Oct 2008 01:04:14 +0000 Subject: [PATCH 05/21] builds with and without mpools (#define USE_MPOOL) but it's still very broked git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4269 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/Makefile.am | 7 +++++-- libclamav/Makefile.in | 12 ++++++++---- libclamav/clamav.h | 6 +----- libclamav/dconf.c | 2 +- libclamav/dconf.h | 3 +-- libclamav/hashtab.c | 14 ++------------ libclamav/hashtab.h | 8 -------- libclamav/matcher-ac.c | 16 ++++++++++++---- libclamav/matcher-bm.c | 2 +- libclamav/matcher.h | 2 +- libclamav/phish_whitelist.c | 4 ++-- libclamav/readdb.c | 15 +++++++-------- libclamav/regex_list.c | 8 ++++---- 13 files changed, 45 insertions(+), 54 deletions(-) diff --git a/libclamav/Makefile.am b/libclamav/Makefile.am index 966bc602f..bbd8fcb61 100644 --- a/libclamav/Makefile.am +++ b/libclamav/Makefile.am @@ -18,7 +18,7 @@ SUBDIRS = lzma . -AM_CPPFLAGS = -I$(top_srcdir) -I@srcdir@/nsis -I@srcdir@/lzma +AM_CPPFLAGS = -I$(top_srcdir) -I@srcdir@/nsis -I@srcdir@/lzma libclamav_la_LIBADD = lzma/liblzma.la @CLAMAV_UNRAR_LIBS@ @LIBCLAMAV_LIBS@ @THREAD_LIBS@ @@ -198,7 +198,10 @@ libclamav_la_SOURCES = \ uniq.c \ uniq.h \ version.c\ - version.h + version.h\ + mpool.c\ + mpool.h\ + mpool_loc.h .PHONY: version.h.tmp version.lo: version.h diff --git a/libclamav/Makefile.in b/libclamav/Makefile.in index bc5d11d29..f48b5108a 100644 --- a/libclamav/Makefile.in +++ b/libclamav/Makefile.in @@ -55,7 +55,7 @@ target_triplet = @target@ @VERSIONSCRIPT_TRUE@am__append_1 = -Wl,@VERSIONSCRIPTFLAG@,@top_srcdir@/libclamav/libclamav.map subdir = libclamav DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in + $(srcdir)/Makefile.in TODO ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/fdpassing.m4 $(top_srcdir)/m4/lib-link.m4 \ @@ -92,7 +92,7 @@ am_libclamav_la_OBJECTS = matcher-ac.lo matcher-bm.lo matcher.lo \ uuencode.lo phishcheck.lo phish_domaincheck_db.lo \ phish_whitelist.lo regex_list.lo regex_suffix.lo mspack.lo \ cab.lo entconv.lo hashtab.lo dconf.lo lzma_iface.lo explode.lo \ - textnorm.lo dlp.lo js-norm.lo uniq.lo version.lo + textnorm.lo dlp.lo js-norm.lo uniq.lo version.lo mpool.lo libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS) libclamav_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -281,7 +281,7 @@ target_vendor = @target_vendor@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = lzma . -AM_CPPFLAGS = -I$(top_srcdir) -I@srcdir@/nsis -I@srcdir@/lzma +AM_CPPFLAGS = -I$(top_srcdir) -I@srcdir@/nsis -I@srcdir@/lzma libclamav_la_LIBADD = lzma/liblzma.la @CLAMAV_UNRAR_LIBS@ @LIBCLAMAV_LIBS@ @THREAD_LIBS@ libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ \ -no-undefined $(am__append_1) @@ -454,7 +454,10 @@ libclamav_la_SOURCES = \ uniq.c \ uniq.h \ version.c\ - version.h + version.h\ + mpool.c\ + mpool.h\ + mpool_loc.h libclamav_internal_utils_la_SOURCES = str.c \ str.h \ @@ -589,6 +592,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mew.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpool.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msexpand.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mspack.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nulsft.Plo@am__quote@ diff --git a/libclamav/clamav.h b/libclamav/clamav.h index ae0ca441e..92831901a 100644 --- a/libclamav/clamav.h +++ b/libclamav/clamav.h @@ -24,10 +24,6 @@ #include #include -#ifdef USE_MPOOL -#include mpool.h -#endif - #ifdef __cplusplus extern "C" { @@ -158,7 +154,7 @@ struct cl_engine { char *pua_cats; #ifdef USE_MPOOL - mpool_t *mempool; + void *mempool; #endif }; diff --git a/libclamav/dconf.c b/libclamav/dconf.c index ec2bb3095..d4186c6cf 100644 --- a/libclamav/dconf.c +++ b/libclamav/dconf.c @@ -113,7 +113,7 @@ static struct dconf_module modules[] = { }; #ifdef USE_MPOOL -struct cli_dconf *cli_dconf_init(mpool_t mempool) +struct cli_dconf *cli_dconf_init(mpool_t *mempool) #else struct cli_dconf *cli_dconf_init(void) #endif diff --git a/libclamav/dconf.h b/libclamav/dconf.h index 6e6983de2..474673b8c 100644 --- a/libclamav/dconf.h +++ b/libclamav/dconf.h @@ -21,7 +21,6 @@ #ifndef __DCONF_H #define __DCONF_H - #include #include @@ -102,7 +101,7 @@ struct cli_dconf { #define PHISHING_CONF_ENTCONV 0x2 #ifdef USE_MPOOL -struct cli_dconf *cli_dconf_init(mpool_t); +struct cli_dconf *cli_dconf_init(mpool_t *); #else struct cli_dconf *cli_dconf_init(void); #endif diff --git a/libclamav/hashtab.c b/libclamav/hashtab.c index 5b1ce9c32..9c76b15a7 100644 --- a/libclamav/hashtab.c +++ b/libclamav/hashtab.c @@ -30,10 +30,6 @@ #include "others.h" #include "hashtab.h" -#ifdef USE_MPOOL -#include "mpool.h" -#endif - #define MODULE_NAME "hashtab: " static const char DELETED_KEY[] = ""; @@ -172,11 +168,7 @@ static inline void PROFILE_REPORT(const struct hashtable *s) #define PROFILE_REPORT(s) #endif -#ifdef USE_MPOOL -int hashtab_init(struct hashtable *s,size_t capacity, mpool_t *mempool) -#else int hashtab_init(struct hashtable *s,size_t capacity) -#endif { if(!s) return CL_ENULLARG; @@ -184,11 +176,9 @@ int hashtab_init(struct hashtable *s,size_t capacity) PROFILE_INIT(s); capacity = nearest_power(capacity); -#ifdef USE_MPOOL - s->htable = mpool_calloc(mempool, capacity,sizeof(*s->htable), NULL); -#else + s->htable = cli_calloc(capacity,sizeof(*s->htable)); -#endif + if(!s->htable) return CL_EMEM; s->capacity = capacity; diff --git a/libclamav/hashtab.h b/libclamav/hashtab.h index 90a594e8f..5dd78085f 100644 --- a/libclamav/hashtab.h +++ b/libclamav/hashtab.h @@ -26,10 +26,6 @@ #include #include "cltypes.h" -#ifdef USE_MPOOL -#include "mpool.h" -#endif - typedef long element_data; /* define this for debugging/profiling purposes only, NOT in production/release code */ @@ -83,11 +79,7 @@ struct hashtable { int hashtab_generate_c(const struct hashtable *s,const char* name); struct element* hashtab_find(const struct hashtable *s, const char* key, const size_t len); -#ifdef USE_MPOOL -int hashtab_init(struct hashtable *s,size_t capacity, mpool_t *mempool); -#else int hashtab_init(struct hashtable *s,size_t capacity); -#endif const struct element* hashtab_insert(struct hashtable *s, const char* key, const size_t len, const element_data data); void hashtab_delete(struct hashtable *s,const char* key,const size_t len); void hashtab_clear(struct hashtable *s); diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c index cdb50d0a5..d056b3ed3 100644 --- a/libclamav/matcher-ac.c +++ b/libclamav/matcher-ac.c @@ -350,7 +350,7 @@ int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth) if(!root->ac_root->trans) { cli_errmsg("cli_ac_init: Can't allocate memory for ac_root->trans\n"); #ifdef USE_MPOOL - mpool_free(engine->mempool, root->ac_root, sizeof(struct cli_ac_node)); + mpool_free(root->mempool, root->ac_root); #else free(root->ac_root); #endif @@ -409,9 +409,17 @@ void cli_ac_free(struct cli_matcher *root) patt->prefix ? free(patt->prefix) : free(patt->pattern); free(patt->virname); if(patt->offset) +#ifdef USE_MPOOL + mpool_free(root->mempool, patt->offset); +#else free(patt->offset); +#endif if(patt->alt) +#ifdef USE_MPOOL + ac_free_alt(root->mempool, patt); +#else ac_free_alt(patt); +#endif free(patt); } if(root->ac_pattable) @@ -1560,14 +1568,14 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(offset) { #ifdef USE_MPOOL - if((new->offset = mpool_alloc(root->mempool, strlen(mpooloffset) + 1, NULL))) + if((new->offset = mpool_alloc(root->mempool, strlen(offset) + 1, NULL))) strcpy(new->offset, offset); #else new->offset = cli_strdup(offset); #endif if(!new->offset) { #ifdef USE_MPOOL - new->prefix ? mpool_free(rool->mempool, new->prefix) : mpool_free(root->mempool, new->pattern); + new->prefix ? mpool_free(root->mempool, new->prefix) : mpool_free(root->mempool, new->pattern); ac_free_alt(root->mempool, new); mpool_free(root->mempool, new->virname); mpool_free(root->mempool, new); @@ -1583,7 +1591,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if((ret = cli_ac_addpatt(root, new))) { #ifdef USE_MPOOL - new->prefix ? mpool_free(rool->mempool, new->prefix) : mpool_free(root->mempool, new->pattern); + new->prefix ? mpool_free(root->mempool, new->prefix) : mpool_free(root->mempool, new->pattern); mpool_free(root->mempool, new->virname); ac_free_alt(root->mempool, new); if(new->offset) diff --git a/libclamav/matcher-bm.c b/libclamav/matcher-bm.c index 4ac58b191..0f82b82e9 100644 --- a/libclamav/matcher-bm.c +++ b/libclamav/matcher-bm.c @@ -110,7 +110,7 @@ int cli_bm_init(struct cli_matcher *root) if(!(root->bm_suffix = (struct cli_bm_patt **) cli_calloc(size, sizeof(struct cli_bm_patt *)))) { #ifdef USE_MPOOL - mpool_free(root->mempool, root->bm_shift, size * sizeof(uint8_t)); + mpool_free(root->mempool, root->bm_shift); #else free(root->bm_shift); #endif diff --git a/libclamav/matcher.h b/libclamav/matcher.h index 0f2762c6b..f98573b55 100644 --- a/libclamav/matcher.h +++ b/libclamav/matcher.h @@ -86,7 +86,7 @@ struct cli_matcher { uint16_t maxpatlen; uint8_t ac_only; #ifdef USE_MPOOL - mpool_t *mempool; + mpool_t *mempool; #endif }; diff --git a/libclamav/phish_whitelist.c b/libclamav/phish_whitelist.c index 12c13753c..591e37525 100644 --- a/libclamav/phish_whitelist.c +++ b/libclamav/phish_whitelist.c @@ -60,8 +60,8 @@ int init_whitelist(struct cl_engine* engine) { if(engine) { #ifdef USE_MPOOL - engine->whitelist_matcher = (struct regex_matcher *) mpool_malloc(engine->mempool, sizeof(struct regex_matcher), NULL); - engine->whitelist_matcher->mempool = engine->mempool; + engine->whitelist_matcher = (struct regex_matcher *) mpool_alloc(engine->mempool, sizeof(struct regex_matcher), NULL); + ((struct regex_matcher *)(engine->whitelist_matcher))->mempool = engine->mempool; #else engine->whitelist_matcher = (struct regex_matcher *) cli_malloc(sizeof(struct regex_matcher)); #endif diff --git a/libclamav/readdb.c b/libclamav/readdb.c index bfc56d574..124d73a43 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -284,7 +284,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex } else { #ifdef USE_MPOOL - bm_new = (struct cli_bm_patt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_bm_patt)); + bm_new = (struct cli_bm_patt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_bm_patt), NULL); #else bm_new = (struct cli_bm_patt *) cli_calloc(1, sizeof(struct cli_bm_patt)); #endif @@ -318,9 +318,8 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex { char *mpoolvirname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); if(mpoolvirname) { - unsigned int mpoolvirnamesz = strlen(mpoolvirname) + 1; - if((bm_new->virname = mpool_alloc(root->mempool, mpoolvirnamesz, NULL))) - memcpy(bm_new->virname, mpoolvirname, mpoolvirname); + if((bm_new->virname = mpool_alloc(root->mempool, strlen(mpoolvirname) + 1, NULL))) + strcpy(bm_new->virname, mpoolvirname); free(mpoolvirname); } else bm_new->virname = NULL; } @@ -340,7 +339,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex if(offset) { #ifdef USE_MPOOL - if((bm_new->offset = mpool_alloc(root->mempool, streln(offset) + 1, NULL))) + if((bm_new->offset = mpool_alloc(root->mempool, strlen(offset) + 1, NULL))) strcpy(bm_new->offset, offset); #else bm_new->offset = cli_strdup(offset); @@ -442,7 +441,7 @@ static int cli_initroots(struct cl_engine *engine, unsigned int options) if(!engine->root[i]) { cli_dbgmsg("Initializing engine->root[%d]\n", i); #ifdef USE_MPOOL - root = engine->root[i] = (struct cli_matcher *) cli_calloc(engine->mempool, 1, sizeof(struct cli_matcher), NULL); + root = engine->root[i] = (struct cli_matcher *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_matcher), NULL); root->mempool = engine->mempool; #else root = engine->root[i] = (struct cli_matcher *) cli_calloc(1, sizeof(struct cli_matcher)); @@ -1098,7 +1097,7 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, root->ac_lsigs++; #ifdef USE_MPOOL - newtable = (struct cli_ac_lsig **) mpool_realloc((*engine)->mempool, root->ac_lsigtable, root->ac_lsigs * sizeof(struct cli_ac_lsig *)); + newtable = (struct cli_ac_lsig **) mpool_resize((*engine)->mempool, root->ac_lsigtable, root->ac_lsigs * sizeof(struct cli_ac_lsig *), NULL); #else newtable = (struct cli_ac_lsig **) cli_realloc(root->ac_lsigtable, root->ac_lsigs * sizeof(struct cli_ac_lsig *)); #endif @@ -1711,7 +1710,7 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, cli_chomp(buffer); #ifdef USE_MPOOL - new = (struct cli_meta_node *) mpool_calloc((*engine)->mempool, 1, sizeof(struct cli_meta_node)); + new = (struct cli_meta_node *) mpool_calloc((*engine)->mempool, 1, sizeof(struct cli_meta_node), NULL); #else new = (struct cli_meta_node *) cli_calloc(1, sizeof(struct cli_meta_node)); #endif diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c index e98390996..1f2d71143 100644 --- a/libclamav/regex_list.c +++ b/libclamav/regex_list.c @@ -356,9 +356,9 @@ int init_regex_list(struct regex_matcher* matcher) matcher->list_built=0; matcher->list_loaded=0; #ifdef USE_MPOOL - hashtab_init(&matcher->suffix_hash, 10, matcher->mempool); - matcher->suffixes->mempool = matcher->mempool; - matcher->md5_hashes->mempool = matcher->mempool; + hashtab_init(&matcher->suffix_hash, 10); + matcher->suffixes.mempool = matcher->mempool; + matcher->md5_hashes.mempool = matcher->mempool; #else hashtab_init(&matcher->suffix_hash, 10); #endif @@ -715,7 +715,7 @@ static regex_t *new_preg(struct regex_matcher *matcher) { regex_t *r; #ifdef USE_MPOOL - matcher->all_pregs = mpool_realloc(matcher->mempool, matcher->all_pregs, ++matcher->regex_cnt * sizeof(*matcher->all_pregs), NULL); + matcher->all_pregs = mpool_resize(matcher->mempool, matcher->all_pregs, ++matcher->regex_cnt * sizeof(*matcher->all_pregs), NULL); #else matcher->all_pregs = cli_realloc(matcher->all_pregs, ++matcher->regex_cnt * sizeof(*matcher->all_pregs)); #endif From b0c3171680291af14f2246f306ab252b33430b34 Mon Sep 17 00:00:00 2001 From: aCaB Date: Sat, 18 Oct 2008 01:05:07 +0000 Subject: [PATCH 06/21] missing symlinks git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4270 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/mpool.c | 1 + libclamav/mpool.h | 1 + libclamav/mpool_loc.h | 1 + 3 files changed, 3 insertions(+) create mode 120000 libclamav/mpool.c create mode 120000 libclamav/mpool.h create mode 120000 libclamav/mpool_loc.h diff --git a/libclamav/mpool.c b/libclamav/mpool.c new file mode 120000 index 000000000..3bbe7f930 --- /dev/null +++ b/libclamav/mpool.c @@ -0,0 +1 @@ +mpool-2.1.0/mpool.c \ No newline at end of file diff --git a/libclamav/mpool.h b/libclamav/mpool.h new file mode 120000 index 000000000..0b1377fca --- /dev/null +++ b/libclamav/mpool.h @@ -0,0 +1 @@ +mpool-2.1.0/mpool.h \ No newline at end of file diff --git a/libclamav/mpool_loc.h b/libclamav/mpool_loc.h new file mode 120000 index 000000000..71c5639bc --- /dev/null +++ b/libclamav/mpool_loc.h @@ -0,0 +1 @@ +mpool-2.1.0/mpool_loc.h \ No newline at end of file From a5746c2512bf3277963a033c9d10c8398fa12d58 Mon Sep 17 00:00:00 2001 From: aCaB Date: Sat, 18 Oct 2008 12:03:08 +0000 Subject: [PATCH 07/21] TODO: - make regex* and hash* behave properly (either include or exclude from the pool entirely) - cleanup the ifdefs and make a single macro - fixup the proto for dconf (re-enables make check in mpool-mode) - check the possibility to entirely wipe frees from error paths in mpool-mode (this totally simplifies the code) git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4271 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/clamav.h | 3 +-- libclamav/dconf.c | 2 +- libclamav/hashtab.c | 2 -- libclamav/hashtab.h | 1 - libclamav/matcher-ac.c | 11 +++++------ libclamav/matcher.h | 1 - libclamav/readdb.c | 10 ++++++---- libclamav/regex_list.c | 6 ------ 8 files changed, 13 insertions(+), 23 deletions(-) diff --git a/libclamav/clamav.h b/libclamav/clamav.h index 92831901a..92b0956c7 100644 --- a/libclamav/clamav.h +++ b/libclamav/clamav.h @@ -153,9 +153,8 @@ struct cl_engine { /* PUA categories (to be included or excluded) */ char *pua_cats; -#ifdef USE_MPOOL + /* Used for memory pools */ void *mempool; -#endif }; struct cl_limits { diff --git a/libclamav/dconf.c b/libclamav/dconf.c index d4186c6cf..fe92aa72c 100644 --- a/libclamav/dconf.c +++ b/libclamav/dconf.c @@ -112,7 +112,7 @@ static struct dconf_module modules[] = { { NULL, NULL, 0, 0 } }; -#ifdef USE_MPOOL +#ifdef USE_MPOOL /* MPOOLFIXME : worthless? */ struct cli_dconf *cli_dconf_init(mpool_t *mempool) #else struct cli_dconf *cli_dconf_init(void) diff --git a/libclamav/hashtab.c b/libclamav/hashtab.c index 9c76b15a7..3747fc839 100644 --- a/libclamav/hashtab.c +++ b/libclamav/hashtab.c @@ -176,9 +176,7 @@ int hashtab_init(struct hashtable *s,size_t capacity) PROFILE_INIT(s); capacity = nearest_power(capacity); - s->htable = cli_calloc(capacity,sizeof(*s->htable)); - if(!s->htable) return CL_EMEM; s->capacity = capacity; diff --git a/libclamav/hashtab.h b/libclamav/hashtab.h index 5dd78085f..98876bd2b 100644 --- a/libclamav/hashtab.h +++ b/libclamav/hashtab.h @@ -25,7 +25,6 @@ #include #include #include "cltypes.h" - typedef long element_data; /* define this for debugging/profiling purposes only, NOT in production/release code */ diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c index d056b3ed3..d9ccbe27a 100644 --- a/libclamav/matcher-ac.c +++ b/libclamav/matcher-ac.c @@ -1444,11 +1444,11 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex #ifdef USE_MPOOL { - unsigned int mpoolhexlen = (strlen(hex ? hex : hexsig) / 2 + 1) * sizeof(uint16_t); + unsigned int mpoolpattsz = (strlen(hex ? hex : hexsig) / 2 + 1) * sizeof(uint16_t); uint16_t *mpoolpatt = cli_hex2ui(hex ? hex : hexsig); if(mpoolpatt) { - if((new->pattern = mpool_alloc(root->mempool, mpoolhexlen, NULL)) != NULL) - memcpy(new->pattern, mpoolpatt, mpoolhexlen); + if((new->pattern = mpool_alloc(root->mempool, mpoolpattsz, NULL)) != NULL) + memcpy(new->pattern, mpoolpatt, mpoolpattsz); free(mpoolpatt); } else new->pattern = NULL; } @@ -1541,9 +1541,8 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex { char *mpoolvirname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); if(mpoolvirname) { - unsigned int mpoolvirnamesz = strlen(mpoolvirname) + 1; - if((new->virname = mpool_alloc(root->mempool, mpoolvirnamesz, NULL)) != NULL) - memcpy(new->virname, mpoolvirname, mpoolvirnamesz); + if((new->virname = mpool_alloc(root->mempool, strlen(mpoolvirname) + 1, NULL)) != NULL) + strcpy(new->virname, mpoolvirname); free(mpoolvirname); } else new->virname = NULL; } diff --git a/libclamav/matcher.h b/libclamav/matcher.h index f98573b55..db3eb3704 100644 --- a/libclamav/matcher.h +++ b/libclamav/matcher.h @@ -38,7 +38,6 @@ #include "mpool.h" #endif - #define CLI_MATCH_WILDCARD 0xff00 #define CLI_MATCH_CHAR 0x0000 #define CLI_MATCH_IGNORE 0x0100 diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 124d73a43..26210ea5f 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -1249,8 +1249,9 @@ static int cli_loadftm(FILE *fs, struct cl_engine **engine, unsigned int options { unsigned char *mpoolmagic = cli_hex2str(tokens[2]); if(mpoolmagic) { - if((new->magic = mpool_alloc((*engine)->mempool, strlen(mpoolmagic) + 1, NULL))) - strcpy(new->magic, mpoolmagic); + unsigned int mpoolmagicsz = strlen(tokens[2]) / 2 + 1; + if((new->magic = mpool_alloc((*engine)->mempool, mpoolmagicsz, NULL))) + memcpy(new->magic, mpoolmagic, mpoolmagicsz); free(mpoolmagic); } else new->magic = NULL; } @@ -1272,8 +1273,9 @@ static int cli_loadftm(FILE *fs, struct cl_engine **engine, unsigned int options { unsigned char *mpooltname = cli_hex2str(tokens[3]); if(mpooltname) { - if((new->tname = mpool_alloc((*engine)->mempool, strlen(mpooltname) + 1, NULL))) - strcpy(new->tname, mpooltname); + unsigned int mpooltnamesz = strlen(tokens[3]) / 2 + 1; + if((new->tname = mpool_alloc((*engine)->mempool, mpooltnamesz, NULL))) + memcpy(new->tname, mpooltname, mpooltnamesz); free(mpooltname); } else new->tname = NULL; } diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c index 1f2d71143..7124d3c27 100644 --- a/libclamav/regex_list.c +++ b/libclamav/regex_list.c @@ -355,13 +355,7 @@ int init_regex_list(struct regex_matcher* matcher) matcher->list_inited=1; matcher->list_built=0; matcher->list_loaded=0; -#ifdef USE_MPOOL - hashtab_init(&matcher->suffix_hash, 10); - matcher->suffixes.mempool = matcher->mempool; - matcher->md5_hashes.mempool = matcher->mempool; -#else hashtab_init(&matcher->suffix_hash, 10); -#endif if((rc = cli_ac_init(&matcher->suffixes, 2, 32))) { return rc; } From e309658f9bf07b6de82af6b853cbed0a508938be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B6r=C3=B6k=20Edvin?= Date: Sun, 19 Oct 2008 10:50:40 +0000 Subject: [PATCH 08/21] strdup not hex2str for tokens[3]! git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4272 77e5149b-7576-45b1-b177-96237e5ba77b --- ChangeLog | 4 ++++ libclamav/readdb.c | 12 +++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 54d9927f6..a580b79d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sun Oct 19 14:13:48 EEST 2008 (edwin) +------------------------------------- + * libclamav/readdb.c: strdup not hex2str for tokens[3]! + Thu Oct 16 11:02:38 CEST 2008 (tk) ---------------------------------- * freshclam/manager.c: fix compilation error on systems without IPv6 (bb#1237) diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 26210ea5f..a228c0c21 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -1270,15 +1270,8 @@ static int cli_loadftm(FILE *fs, struct cl_engine **engine, unsigned int options } new->length = strlen(tokens[2]) / 2; #ifdef USE_MPOOL -{ - unsigned char *mpooltname = cli_hex2str(tokens[3]); - if(mpooltname) { - unsigned int mpooltnamesz = strlen(tokens[3]) / 2 + 1; - if((new->tname = mpool_alloc((*engine)->mempool, mpooltnamesz, NULL))) - memcpy(new->tname, mpooltname, mpooltnamesz); - free(mpooltname); - } else new->tname = NULL; -} + if((new->tname = mpool_alloc((*engine)->mempool, strlen(tokens[3])+1, NULL))) + strcpy(new->tname, tokens[3]); #else new->tname = cli_strdup(tokens[3]); #endif @@ -2461,6 +2454,7 @@ void cl_free(struct cl_engine *engine) #endif #ifdef USE_MPOOL + printf("here\n"); if(engine->mempool) mpool_close(engine->mempool); #else if(engine->root) { From 04dc5e0ae5138a9ed0065cc4450d30ae3b6527f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B6r=C3=B6k=20Edvin?= Date: Sun, 19 Oct 2008 10:51:22 +0000 Subject: [PATCH 09/21] remove debug message git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4273 77e5149b-7576-45b1-b177-96237e5ba77b --- ChangeLog | 4 ++++ libclamav/readdb.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a580b79d3..22f4fface 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sun Oct 19 14:14:32 EEST 2008 (edwin) +------------------------------------- + * libclamav/readdb.c: remove debug message + Sun Oct 19 14:13:48 EEST 2008 (edwin) ------------------------------------- * libclamav/readdb.c: strdup not hex2str for tokens[3]! diff --git a/libclamav/readdb.c b/libclamav/readdb.c index a228c0c21..3a701212e 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -2454,7 +2454,6 @@ void cl_free(struct cl_engine *engine) #endif #ifdef USE_MPOOL - printf("here\n"); if(engine->mempool) mpool_close(engine->mempool); #else if(engine->root) { From 6e2a411334084dbb57c295d07f4d5277e3f822a0 Mon Sep 17 00:00:00 2001 From: aCaB Date: Sun, 19 Oct 2008 11:30:53 +0000 Subject: [PATCH 10/21] make _resize properly behave git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4274 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/mpool-2.1.0/mpool.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libclamav/mpool-2.1.0/mpool.c b/libclamav/mpool-2.1.0/mpool.c index 5e67c5c8e..a9068f0f4 100644 --- a/libclamav/mpool-2.1.0/mpool.c +++ b/libclamav/mpool-2.1.0/mpool.c @@ -1368,8 +1368,7 @@ int mpool_free(mpool_t *mp_p, void *addr) * * ARGUMENTS: * - * mp_p <-> Pointer to the memory pool. If NULL then it will do a - * normal realloc. + * mp_p <-> Pointer to the memory pool. * * old_addr -> Previously allocated address. * @@ -1391,6 +1390,11 @@ void *mpool_resize(mpool_t *mp_p, void *old_addr, int ret; struct FRAG *old_frag = (struct FRAG *)(old_addr - FRAG_OVERHEAD); unsigned long old_byte_size; + + if (old_addr == NULL) { + /* behave like realloc */ + return mpool_alloc(mp_p, new_byte_size, error_p); + } if (!mp_p || mp_p->mp_magic != MPOOL_MAGIC) { SET_POINTER(error_p, MPOOL_ERROR_PNT); @@ -1401,11 +1405,6 @@ void *mpool_resize(mpool_t *mp_p, void *old_addr, return NULL; } - if (old_addr == NULL) { - SET_POINTER(error_p, MPOOL_ERROR_ARG_NULL); - return NULL; - } - old_byte_size = old_frag->frag_size; if (old_byte_size == 0) { SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); From 29f241666fcf6d1bf0a43b9299d406ed206658b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B6r=C3=B6k=20Edvin?= Date: Sun, 19 Oct 2008 12:13:24 +0000 Subject: [PATCH 11/21] fix hexnew allocation, mempool for regex_list git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4276 77e5149b-7576-45b1-b177-96237e5ba77b --- ChangeLog | 5 +++++ libclamav/matcher-ac.c | 5 ----- libclamav/regex_list.c | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 22f4fface..7c253b662 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sun Oct 19 15:36:32 EEST 2008 (edwin) +------------------------------------- + * libclamav/matcher-ac.c, libclamav/regex_list.c: fix hexnew + allocation, mempool for regex_list + Sun Oct 19 14:14:32 EEST 2008 (edwin) ------------------------------------- * libclamav/readdb.c: remove debug message diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c index d9ccbe27a..254a1a857 100644 --- a/libclamav/matcher-ac.c +++ b/libclamav/matcher-ac.c @@ -1286,13 +1286,8 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex return CL_EMEM; } -#ifdef USE_MPOOL - if(!(hexnew = (char *) mpool_calloc(root->mempool, strlen(hexsig) + 1, 1, NULL))) { - mpool_free(root->mempool, new); -#else if(!(hexnew = (char *) cli_calloc(strlen(hexsig) + 1, 1))) { free(new); -#endif free(hexcpy); return CL_EMEM; } diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c index 7124d3c27..4f0ffa535 100644 --- a/libclamav/regex_list.c +++ b/libclamav/regex_list.c @@ -356,6 +356,7 @@ int init_regex_list(struct regex_matcher* matcher) matcher->list_built=0; matcher->list_loaded=0; hashtab_init(&matcher->suffix_hash, 10); + matcher->suffixes.mempool = matcher->mempool; if((rc = cli_ac_init(&matcher->suffixes, 2, 32))) { return rc; } From b36e9f8a1a602e153a300d9121e8bc9d166bef4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B6r=C3=B6k=20Edvin?= Date: Sun, 19 Oct 2008 12:27:59 +0000 Subject: [PATCH 12/21] mempool for regex_list/phishcheck git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4277 77e5149b-7576-45b1-b177-96237e5ba77b --- ChangeLog | 6 ++++++ libclamav/phish_domaincheck_db.c | 1 + libclamav/phish_whitelist.c | 3 +++ libclamav/phishcheck.c | 2 ++ libclamav/regex_list.c | 9 ++++++++- 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7c253b662..f1401443f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Sun Oct 19 15:51:10 EEST 2008 (edwin) +------------------------------------- + * libclamav/phish_domaincheck_db.c, libclamav/phish_whitelist.c, + libclamav/phishcheck.c, libclamav/regex_list.c: mempool for + regex_list/phishcheck + Sun Oct 19 15:36:32 EEST 2008 (edwin) ------------------------------------- * libclamav/matcher-ac.c, libclamav/regex_list.c: fix hexnew diff --git a/libclamav/phish_domaincheck_db.c b/libclamav/phish_domaincheck_db.c index f71e1a2f3..0fdb0e20f 100644 --- a/libclamav/phish_domaincheck_db.c +++ b/libclamav/phish_domaincheck_db.c @@ -58,6 +58,7 @@ int init_domainlist(struct cl_engine* engine) engine->domainlist_matcher = (struct regex_matcher *) cli_malloc(sizeof(struct regex_matcher)); if(!engine->domainlist_matcher) return CL_EMEM; + ((struct regex_matcher*)engine->domainlist_matcher)->mempool = engine->mempool; return init_regex_list(engine->domainlist_matcher); } else diff --git a/libclamav/phish_whitelist.c b/libclamav/phish_whitelist.c index 591e37525..2da929de7 100644 --- a/libclamav/phish_whitelist.c +++ b/libclamav/phish_whitelist.c @@ -65,6 +65,7 @@ int init_whitelist(struct cl_engine* engine) #else engine->whitelist_matcher = (struct regex_matcher *) cli_malloc(sizeof(struct regex_matcher)); #endif + ((struct regex_matcher*)engine->whitelist_matcher)->mempool = engine->mempool; if(!engine->whitelist_matcher) return CL_EMEM; return init_regex_list(engine->whitelist_matcher); @@ -82,7 +83,9 @@ void whitelist_done(struct cl_engine* engine) { if(engine && engine->whitelist_matcher) { regex_list_done(engine->whitelist_matcher); +#ifndef USE_MPOOL free(engine->whitelist_matcher); +#endif engine->whitelist_matcher = NULL; } } diff --git a/libclamav/phishcheck.c b/libclamav/phishcheck.c index d7bef7449..0d935ed13 100644 --- a/libclamav/phishcheck.c +++ b/libclamav/phishcheck.c @@ -907,7 +907,9 @@ void phishing_done(struct cl_engine* engine) domainlist_done(engine); if(pchk) { cli_dbgmsg("Freeing phishcheck struct\n"); +#ifndef USE_MPOOL free(pchk); +#endif } cli_dbgmsg("Phishcheck cleaned up\n"); } diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c index 4f0ffa535..f872d21b3 100644 --- a/libclamav/regex_list.c +++ b/libclamav/regex_list.c @@ -347,6 +347,7 @@ int regex_list_match(struct regex_matcher* matcher,char* real_url,const char* di /* Initializes @matcher, allocating necesarry substructures */ int init_regex_list(struct regex_matcher* matcher) { + mpool_t *mp = matcher->mempool; int rc; assert(matcher); @@ -356,10 +357,12 @@ int init_regex_list(struct regex_matcher* matcher) matcher->list_built=0; matcher->list_loaded=0; hashtab_init(&matcher->suffix_hash, 10); - matcher->suffixes.mempool = matcher->mempool; + matcher->mempool = mp; + matcher->suffixes.mempool = mp; if((rc = cli_ac_init(&matcher->suffixes, 2, 32))) { return rc; } + matcher->md5_hashes.mempool = mp; if((rc = cli_bm_init(&matcher->md5_hashes))) { return rc; } @@ -568,7 +571,9 @@ void regex_list_done(struct regex_matcher* matcher) if(matcher->list_inited) { size_t i; +#ifndef USE_MPOOL cli_ac_free(&matcher->suffixes); +#endif if(matcher->suffix_regexes) { for(i=0;isuffix_cnt;i++) { struct regex_list *r = matcher->suffix_regexes[i].head; @@ -591,7 +596,9 @@ void regex_list_done(struct regex_matcher* matcher) free(matcher->all_pregs); } hashtab_free(&matcher->suffix_hash); +#ifndef USE_MPOOL cli_bm_free(&matcher->md5_hashes); +#endif } } From 4284b788bce73f5dff94fb3ed2746c6c4835bd66 Mon Sep 17 00:00:00 2001 From: aCaB Date: Sun, 19 Oct 2008 12:32:36 +0000 Subject: [PATCH 13/21] freeign0 git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4278 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/readdb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 3a701212e..8d600c3f4 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -1437,9 +1437,15 @@ static void cli_freeign(struct cl_engine *engine) while(ignored->list) { pt = ignored->list; ignored->list = ignored->list->next; +#ifdef USE_MPOOL + mpool_free(engine->mempool, pt->dbname); + mpool_free(engine->mempool, pt->signame); + mpool_free(engine->mempool,pt); +#else free(pt->dbname); free(pt->signame); free(pt); +#endif } hashset_destroy(&ignored->hs); free(engine->ignored); From 0d9dbdef21555b320e09c9f3727296a1d88d234a Mon Sep 17 00:00:00 2001 From: aCaB Date: Sun, 19 Oct 2008 16:16:49 +0000 Subject: [PATCH 14/21] some leaks fixed git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4280 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/filetypes.c | 10 +++++++-- libclamav/filetypes.h | 2 +- libclamav/matcher-ac.c | 32 +++++++++++++++++++++++++++- libclamav/matcher-bm.c | 33 +++++++++++++++++++++++++++++ libclamav/matcher.h | 3 +++ libclamav/mpool-2.1.0/mpool.c | 15 +++++++++++++- libclamav/mpool-2.1.0/mpool.h | 4 ++++ libclamav/phish_whitelist.c | 6 ++++-- libclamav/phishcheck.c | 4 +++- libclamav/readdb.c | 39 ++++++++++++++++++++++++++++++----- libclamav/regex_list.c | 12 +++++++---- 11 files changed, 143 insertions(+), 17 deletions(-) diff --git a/libclamav/filetypes.c b/libclamav/filetypes.c index d5eeb9195..9a5ac3273 100644 --- a/libclamav/filetypes.c +++ b/libclamav/filetypes.c @@ -100,16 +100,22 @@ cli_file_t cli_ftcode(const char *name) return CL_TYPE_ERROR; } -void cli_ftfree(struct cli_ftype *ftypes) +void cli_ftfree(const struct cl_engine *engine) { - struct cli_ftype *pt; + struct cli_ftype *ftypes=engine->ftypes, *pt; while(ftypes) { pt = ftypes; ftypes = ftypes->next; +#ifdef USE_MPOOL + mpool_free(engine->mempool, pt->magic); + mpool_free(engine->mempool, pt->tname); + mpool_free(engine->mempool, pt); +#else free(pt->magic); free(pt->tname); free(pt); +#endif } } diff --git a/libclamav/filetypes.h b/libclamav/filetypes.h index 720449f3b..ecfb21613 100644 --- a/libclamav/filetypes.h +++ b/libclamav/filetypes.h @@ -95,7 +95,7 @@ struct cli_matched_type { }; cli_file_t cli_ftcode(const char *name); -void cli_ftfree(struct cli_ftype *ftypes); +void cli_ftfree(const struct cl_engine *engine); cli_file_t cli_filetype(const unsigned char *buf, size_t buflen, const struct cl_engine *engine); cli_file_t cli_filetype2(int desc, const struct cl_engine *engine); int cli_addtypesigs(struct cl_engine *engine); diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c index 254a1a857..3215af89b 100644 --- a/libclamav/matcher-ac.c +++ b/libclamav/matcher-ac.c @@ -406,8 +406,16 @@ void cli_ac_free(struct cli_matcher *root) for(i = 0; i < root->ac_patterns; i++) { patt = root->ac_pattable[i]; +#ifdef USE_MPOOL + patt->prefix ? mpool_free(root->mempool, patt->prefix) : mpool_free(root->mempool, patt->pattern); +#else patt->prefix ? free(patt->prefix) : free(patt->pattern); +#endif +#ifdef USE_MPOOL + mpool_free(root->mempool, patt->virname); +#else free(patt->virname); +#endif if(patt->offset) #ifdef USE_MPOOL mpool_free(root->mempool, patt->offset); @@ -420,23 +428,45 @@ void cli_ac_free(struct cli_matcher *root) #else ac_free_alt(patt); #endif +#ifdef USE_MPOOL + mpool_free(root->mempool, patt); + +#else free(patt); +#endif } if(root->ac_pattable) +#ifdef USE_MPOOL + mpool_free(root->mempool, root->ac_pattable); +#else free(root->ac_pattable); +#endif for(i = 0; i < root->ac_nodes; i++) { if(!root->ac_nodetable[i]->leaf) +#ifdef USE_MPOOL + mpool_free(root->mempool, root->ac_nodetable[i]->trans); + mpool_free(root->mempool, root->ac_nodetable[i]); +#else free(root->ac_nodetable[i]->trans); free(root->ac_nodetable[i]); +#endif } if(root->ac_nodetable) +#ifdef USE_MPOOL + mpool_free(root->mempool, root->ac_nodetable); +#else free(root->ac_nodetable); - +#endif if(root->ac_root) { +#ifdef USE_MPOOL + mpool_free(root->mempool, root->ac_root->trans); + mpool_free(root->mempool, root->ac_root); +#else free(root->ac_root->trans); free(root->ac_root); +#endif } } diff --git a/libclamav/matcher-bm.c b/libclamav/matcher-bm.c index 0f82b82e9..974507a8f 100644 --- a/libclamav/matcher-bm.c +++ b/libclamav/matcher-bm.c @@ -108,7 +108,11 @@ int cli_bm_init(struct cli_matcher *root) #endif return CL_EMEM; +#ifdef USE_MPOOL + if(!(root->bm_suffix = (struct cli_bm_patt **) mpool_calloc(root->mempool, size, sizeof(struct cli_bm_patt *), NULL))) { +#else if(!(root->bm_suffix = (struct cli_bm_patt **) cli_calloc(size, sizeof(struct cli_bm_patt *)))) { +#endif #ifdef USE_MPOOL mpool_free(root->mempool, root->bm_shift); #else @@ -130,7 +134,11 @@ void cli_bm_free(struct cli_matcher *root) if(root->bm_shift) +#ifdef USE_MPOOL + mpool_free(root->mempool, root->bm_shift); +#else free(root->bm_shift); +#endif if(root->bm_suffix) { for(i = 0; i < size; i++) { @@ -139,17 +147,42 @@ void cli_bm_free(struct cli_matcher *root) prev = patt; patt = patt->next; if(prev->prefix) +#ifdef USE_MPOOL + mpool_free(root->mempool, prev->prefix); +#else free(prev->prefix); +#endif else +#ifdef USE_MPOOL + mpool_free(root->mempool, prev->pattern); +#else free(prev->pattern); +#endif if(prev->virname) +#ifdef USE_MPOOL + mpool_free(root->mempool, prev->virname); +#else free(prev->virname); +#endif if(prev->offset) +#ifdef USE_MPOOL + mpool_free(root->mempool, prev->offset); +#else free(prev->offset); +#endif +#ifdef USE_MPOOL + mpool_free(root->mempool, prev); +#else free(prev); +#endif + } } +#ifdef USE_MPOOL + mpool_free(root->mempool, root->bm_suffix); +#else free(root->bm_suffix); +#endif } } diff --git a/libclamav/matcher.h b/libclamav/matcher.h index db3eb3704..44cd2e89f 100644 --- a/libclamav/matcher.h +++ b/libclamav/matcher.h @@ -58,6 +58,9 @@ struct cli_lsig_tdb { const uint32_t *engine, *nos, *ep; const uint32_t *sectoff, *sectrva, *sectvsz, *sectraw, *sectrsz, *secturva, *sectuvsz, *secturaw, *sectursz; +#ifdef USE_MPOOL + mpool_t *mempool; +#endif }; struct cli_ac_lsig { diff --git a/libclamav/mpool-2.1.0/mpool.c b/libclamav/mpool-2.1.0/mpool.c index a9068f0f4..12eac5374 100644 --- a/libclamav/mpool-2.1.0/mpool.c +++ b/libclamav/mpool-2.1.0/mpool.c @@ -789,6 +789,7 @@ static void *alloc_mem(mpool_t *mp_p, const unsigned long byte_size, } SET_POINTER(error_p, MPOOL_ERROR_NONE); + // printf("^alloc'd %p::%p(%u)\n", mp_p, addr, byte_size); return addr; } @@ -819,6 +820,8 @@ static int free_mem(mpool_t *mp_p, void *addr, const unsigned long size) unsigned long old_size, fence; int ret; mpool_block_t *block_p; + + // printf("free'd %p::%p(%u)\n", mp_p, addr, size); /* * If the size is larger than a block then the allocation must be at @@ -862,7 +865,6 @@ static int free_mem(mpool_t *mp_p, void *addr, const unsigned long size) /* adjust our stats */ mp_p->mp_alloc_c--; - return MPOOL_ERROR_NONE; } @@ -1494,6 +1496,17 @@ void *mpool_resize(mpool_t *mp_p, void *old_addr, return &new_frag->frag_ptr; } + +void *mpool_resize2(mpool_t *mp_p, void *old_addr, + const unsigned long new_byte_size, + int *error_p) +{ + void *alloc = mpool_resize(mp_p, old_addr, new_byte_size, error_p); + if(!alloc && old_addr) + mpool_free(mp_p, old_addr); + return alloc; +} + /* * int mpool_stats * diff --git a/libclamav/mpool-2.1.0/mpool.h b/libclamav/mpool-2.1.0/mpool.h index 5d8a8f528..7368a223f 100644 --- a/libclamav/mpool-2.1.0/mpool.h +++ b/libclamav/mpool-2.1.0/mpool.h @@ -343,6 +343,10 @@ extern void *mpool_resize(mpool_t *mp_p, void *old_addr, const unsigned long new_byte_size, int *error_p); +extern +void *mpool_resize2(mpool_t *mp_p, void *old_addr, + const unsigned long new_byte_size, + int *error_p); /* * int mpool_stats diff --git a/libclamav/phish_whitelist.c b/libclamav/phish_whitelist.c index 2da929de7..ed07a98c8 100644 --- a/libclamav/phish_whitelist.c +++ b/libclamav/phish_whitelist.c @@ -82,8 +82,10 @@ int is_whitelist_ok(const struct cl_engine* engine) void whitelist_done(struct cl_engine* engine) { if(engine && engine->whitelist_matcher) { - regex_list_done(engine->whitelist_matcher); -#ifndef USE_MPOOL + regex_list_done(engine->whitelist_matcher); +#ifdef USE_MPOOL + mpool_free(engine->mempool, engine->whitelist_matcher); +#else free(engine->whitelist_matcher); #endif engine->whitelist_matcher = NULL; diff --git a/libclamav/phishcheck.c b/libclamav/phishcheck.c index 0d935ed13..e639f90ce 100644 --- a/libclamav/phishcheck.c +++ b/libclamav/phishcheck.c @@ -907,7 +907,9 @@ void phishing_done(struct cl_engine* engine) domainlist_done(engine); if(pchk) { cli_dbgmsg("Freeing phishcheck struct\n"); -#ifndef USE_MPOOL +#ifdef USE_MPOOL + mpool_free(engine->mempool, pchk); +#else free(pchk); #endif } diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 8d600c3f4..006479b89 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -867,7 +867,11 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) switch(apt->type) { case CLI_TDB_UINT: off[i] = cnt = tdb->cnt[CLI_TDB_UINT]++; +#ifdef USE_MPOOL + tdb->val = (uint32_t *) mpool_resize2(tdb->mempool, tdb->val, tdb->cnt[CLI_TDB_UINT] * sizeof(uint32_t), NULL); +#else tdb->val = (uint32_t *) cli_realloc2(tdb->val, tdb->cnt[CLI_TDB_UINT] * sizeof(uint32_t)); +#endif if(!tdb->val) { tdb->cnt[CLI_TDB_UINT] = 0; return -1; @@ -883,7 +887,11 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) *pt2++ = 0; off[i] = cnt = tdb->cnt[CLI_TDB_RANGE]; tdb->cnt[CLI_TDB_RANGE] += 2; +#ifdef USE_MPOOL + tdb->range = (uint32_t *) mpool_resize2(tdb->mempool, tdb->range, tdb->cnt[CLI_TDB_RANGE] * sizeof(uint32_t), NULL); +#else tdb->range = (uint32_t *) cli_realloc2(tdb->range, tdb->cnt[CLI_TDB_RANGE] * sizeof(uint32_t)); +#endif if(!tdb->range) { tdb->cnt[CLI_TDB_RANGE] = 0; return -1; @@ -899,7 +907,11 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) } off[i] = cnt = tdb->cnt[CLI_TDB_RANGE]; tdb->cnt[CLI_TDB_RANGE] += 3; +#ifdef USE_MPOOL + tdb->range = (uint32_t *) mpool_resize2(tdb->mempool, tdb->range, tdb->cnt[CLI_TDB_RANGE] * sizeof(uint32_t), NULL); +#else tdb->range = (uint32_t *) cli_realloc2(tdb->range, tdb->cnt[CLI_TDB_RANGE] * sizeof(uint32_t)); +#endif if(!tdb->range) { tdb->cnt[CLI_TDB_RANGE] = 0; return -1; @@ -916,7 +928,11 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) case CLI_TDB_STR: off[i] = cnt = tdb->cnt[CLI_TDB_STR]; tdb->cnt[CLI_TDB_STR] += strlen(pt) + 1; +#ifdef USE_MPOOL + tdb->str = (char *) mpool_resize2(tdb->mempool, tdb->str, tdb->cnt[CLI_TDB_STR] * sizeof(char), NULL); +#else tdb->str = (char *) cli_realloc2(tdb->str, tdb->cnt[CLI_TDB_STR] * sizeof(char)); +#endif if(!tdb->str) { cli_errmsg("lsigattribs: Can't allocate memory for tdb->str\n"); return -1; @@ -958,6 +974,16 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) return 0; } +#ifdef USE_MPOOL +#define FREE_TDB(x) do { \ + if(x.cnt[CLI_TDB_UINT]) \ + mpool_free(x.mempool, x.val); \ + if(x.cnt[CLI_TDB_RANGE]) \ + mpool_free(x.mempool, x.range); \ + if(x.cnt[CLI_TDB_STR]) \ + mpool_free(x.mempool, x.str); \ + } while(0); +#else #define FREE_TDB(x) \ if(x.cnt[CLI_TDB_UINT]) \ free(x.val); \ @@ -965,6 +991,7 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) free(x.range); \ if(x.cnt[CLI_TDB_STR]) \ free(x.str); +#endif #define LDB_TOKENS 67 static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio, const char *dbname) @@ -1030,6 +1057,7 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, /* TDB */ memset(&tdb, 0, sizeof(tdb)); + tdb.mempool = (*engine)->mempool; if(lsigattribs(tokens[1], &tdb) == -1) { FREE_TDB(tdb); @@ -2458,10 +2486,9 @@ void cl_free(struct cl_engine *engine) #ifdef CL_THREAD_SAFE pthread_mutex_unlock(&cli_ref_mutex); #endif - #ifdef USE_MPOOL - if(engine->mempool) mpool_close(engine->mempool); -#else +#define free(X) mpool_free(engine->mempool, X) +#endif if(engine->root) { for(i = 0; i < CLI_MTARGETS; i++) { if((root = engine->root[i])) { @@ -2523,15 +2550,17 @@ void cl_free(struct cl_engine *engine) if(((struct cli_dconf *) engine->dconf)->phishing & PHISHING_CONF_ENGINE) phishing_done(engine); - if(engine->dconf) free(engine->dconf); if(engine->pua_cats) free(engine->pua_cats); - cli_ftfree(engine->ftypes); + cli_ftfree(engine); cli_freeign(engine); +#ifdef USE_MPOOL +#undef free(X) + if(engine->mempool) mpool_close(engine->mempool); #endif /* USE_MPOOL */ free(engine); } diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c index f872d21b3..165df80c0 100644 --- a/libclamav/regex_list.c +++ b/libclamav/regex_list.c @@ -571,9 +571,7 @@ void regex_list_done(struct regex_matcher* matcher) if(matcher->list_inited) { size_t i; -#ifndef USE_MPOOL cli_ac_free(&matcher->suffixes); -#endif if(matcher->suffix_regexes) { for(i=0;isuffix_cnt;i++) { struct regex_list *r = matcher->suffix_regexes[i].head; @@ -591,14 +589,20 @@ void regex_list_done(struct regex_matcher* matcher) for(i=0;iregex_cnt;i++) { regex_t *r = matcher->all_pregs[i]; cli_regfree(r); +#ifdef USE_MPOOL + mpool_free(matcher->mempool, r); +#else free(r); +#endif } +#ifdef USE_MPOOL + mpool_free(matcher->mempool, matcher->all_pregs); +#else free(matcher->all_pregs); +#endif } hashtab_free(&matcher->suffix_hash); -#ifndef USE_MPOOL cli_bm_free(&matcher->md5_hashes); -#endif } } From d22176efd2f679f050daea87f3d81e5d47f73099 Mon Sep 17 00:00:00 2001 From: aCaB Date: Sun, 19 Oct 2008 17:27:37 +0000 Subject: [PATCH 15/21] MERGE COMPLETE TODO - unuglify the ifdefs - reenable make checks - rework mpool.c - test git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4281 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/readdb.c | 12 ++++++++++++ libclamav/regex_list.c | 17 +++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 006479b89..6d598f5c9 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -2570,7 +2570,19 @@ static void cli_md5db_build(struct cli_matcher* root) if(root && root->md5_sizes_hs.capacity) { /* TODO: use hashset directly, instead of the array when matching*/ cli_dbgmsg("Converting hashset to array: %lu entries\n", root->md5_sizes_hs.count); + +#ifdef USE_MPOOL + { + uint32_t *mpoolht; + unsigned int mpoolhtsz = root->md5_sizes_hs.count * sizeof(*mpoolht); + root->soff = mpool_alloc(root->mempool, mpoolhtsz, NULL); + root->soff_len = hashset_toarray(&root->md5_sizes_hs, &mpoolht); + memcpy(root->soff, mpoolht, mpoolhtsz); + free(mpoolht); + } +#else root->soff_len = hashset_toarray(&root->md5_sizes_hs, &root->soff); +#endif hashset_destroy(&root->md5_sizes_hs); qsort(root->soff, root->soff_len, sizeof(uint32_t), scomp); } diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c index 165df80c0..da7baec04 100644 --- a/libclamav/regex_list.c +++ b/libclamav/regex_list.c @@ -615,7 +615,11 @@ int is_regex_ok(struct regex_matcher* matcher) static int add_newsuffix(struct regex_matcher *matcher, struct regex_list *info, const char *suffix, size_t len) { struct cli_matcher *root = &matcher->suffixes; +#ifdef USE_MPOOL + struct cli_ac_patt *new = mpool_calloc(matcher->mempool,1,sizeof(*new),NULL); +#else struct cli_ac_patt *new = cli_calloc(1,sizeof(*new)); +#endif size_t i; int ret; @@ -637,9 +641,17 @@ static int add_newsuffix(struct regex_matcher *matcher, struct regex_list *info, if(new->length > root->maxpatlen) root->maxpatlen = new->length; +#ifdef USE_MPOOL + new->pattern = mpool_alloc(matcher->mempool, sizeof(new->pattern[0])*len, NULL); +#else new->pattern = cli_malloc(sizeof(new->pattern[0])*len); +#endif if(!new->pattern) { +#ifdef USE_MPOOL + mpool_free(matcher->mempool, new); +#else free(new); +#endif return CL_EMEM; } for(i=0;icustomdata = info; new->virname = NULL; if((ret = cli_ac_addpatt(root,new))) { +#ifdef USE_MPOOL + mpool_free(matcher->mempool, new->pattern); + mpool_free(matcher->mempool, new); +#else free(new->pattern); free(new); +#endif return ret; } SO_preprocess_add(&matcher->filter, (const unsigned char*)suffix, len); From 1e2969a4e1a7d96209212319bd8f5668cfb4fd66 Mon Sep 17 00:00:00 2001 From: aCaB Date: Sun, 19 Oct 2008 17:57:09 +0000 Subject: [PATCH 16/21] reenable non-mpooll builds git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4282 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/phish_domaincheck_db.c | 2 ++ libclamav/phish_whitelist.c | 1 - libclamav/readdb.c | 2 ++ libclamav/regex_list.c | 6 ++++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libclamav/phish_domaincheck_db.c b/libclamav/phish_domaincheck_db.c index 0fdb0e20f..1bc29d467 100644 --- a/libclamav/phish_domaincheck_db.c +++ b/libclamav/phish_domaincheck_db.c @@ -58,7 +58,9 @@ int init_domainlist(struct cl_engine* engine) engine->domainlist_matcher = (struct regex_matcher *) cli_malloc(sizeof(struct regex_matcher)); if(!engine->domainlist_matcher) return CL_EMEM; +#ifdef USE_MPOOL ((struct regex_matcher*)engine->domainlist_matcher)->mempool = engine->mempool; +#endif return init_regex_list(engine->domainlist_matcher); } else diff --git a/libclamav/phish_whitelist.c b/libclamav/phish_whitelist.c index ed07a98c8..f0e0063e4 100644 --- a/libclamav/phish_whitelist.c +++ b/libclamav/phish_whitelist.c @@ -65,7 +65,6 @@ int init_whitelist(struct cl_engine* engine) #else engine->whitelist_matcher = (struct regex_matcher *) cli_malloc(sizeof(struct regex_matcher)); #endif - ((struct regex_matcher*)engine->whitelist_matcher)->mempool = engine->mempool; if(!engine->whitelist_matcher) return CL_EMEM; return init_regex_list(engine->whitelist_matcher); diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 6d598f5c9..b9846efdb 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -1057,7 +1057,9 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, /* TDB */ memset(&tdb, 0, sizeof(tdb)); +#ifdef USE_MEMPOOL tdb.mempool = (*engine)->mempool; +#endif if(lsigattribs(tokens[1], &tdb) == -1) { FREE_TDB(tdb); diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c index da7baec04..0fc42fd81 100644 --- a/libclamav/regex_list.c +++ b/libclamav/regex_list.c @@ -347,7 +347,9 @@ int regex_list_match(struct regex_matcher* matcher,char* real_url,const char* di /* Initializes @matcher, allocating necesarry substructures */ int init_regex_list(struct regex_matcher* matcher) { +#ifdef USE_MPOOL mpool_t *mp = matcher->mempool; +#endif int rc; assert(matcher); @@ -357,12 +359,16 @@ int init_regex_list(struct regex_matcher* matcher) matcher->list_built=0; matcher->list_loaded=0; hashtab_init(&matcher->suffix_hash, 10); +#ifdef USE_MPOOL matcher->mempool = mp; matcher->suffixes.mempool = mp; +#endif if((rc = cli_ac_init(&matcher->suffixes, 2, 32))) { return rc; } +#ifdef USE_MPOOL matcher->md5_hashes.mempool = mp; +#endif if((rc = cli_bm_init(&matcher->md5_hashes))) { return rc; } From a963dd9257251e4bd3db4fdb6cdf421dfdf97ac4 Mon Sep 17 00:00:00 2001 From: aCaB Date: Sun, 19 Oct 2008 22:58:53 +0000 Subject: [PATCH 17/21] typo git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4283 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/readdb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libclamav/readdb.c b/libclamav/readdb.c index b9846efdb..703e02243 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -398,7 +398,7 @@ int cli_initengine(struct cl_engine **engine, unsigned int options) (*engine)->refcount = 1; #ifdef USE_MPOOL - if(!((*engine)->mempool = mpool_open(MPOOL_FLAG_BEST_FIT, 0, NULL, NULL))) { + if(!((*engine)->mempool = mpool_open(MPOOL_FLAG_HEAVY_PACKING | MPOOL_FLAG_BEST_FIT, 0, NULL, NULL))) { cli_errmsg("Can't allocate memory for memory pool!\n"); return CL_EMEM; } @@ -1057,7 +1057,7 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, /* TDB */ memset(&tdb, 0, sizeof(tdb)); -#ifdef USE_MEMPOOL +#ifdef USE_MPOOL tdb.mempool = (*engine)->mempool; #endif From eb8ab9d28a237d2bd79ec5ee827000471a689299 Mon Sep 17 00:00:00 2001 From: aCaB Date: Tue, 21 Oct 2008 23:54:03 +0000 Subject: [PATCH 18/21] bloody svn sucks git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4285 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/mpool.c | 1 - libclamav/mpool.h | 1 - 2 files changed, 2 deletions(-) delete mode 120000 libclamav/mpool.c delete mode 120000 libclamav/mpool.h diff --git a/libclamav/mpool.c b/libclamav/mpool.c deleted file mode 120000 index 3bbe7f930..000000000 --- a/libclamav/mpool.c +++ /dev/null @@ -1 +0,0 @@ -mpool-2.1.0/mpool.c \ No newline at end of file diff --git a/libclamav/mpool.h b/libclamav/mpool.h deleted file mode 120000 index 0b1377fca..000000000 --- a/libclamav/mpool.h +++ /dev/null @@ -1 +0,0 @@ -mpool-2.1.0/mpool.h \ No newline at end of file From e21657dfc9e605692769c3c52d5fcaf403915fbe Mon Sep 17 00:00:00 2001 From: aCaB Date: Tue, 21 Oct 2008 23:55:11 +0000 Subject: [PATCH 19/21] a faster and more compact allocator git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4286 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/dconf.c | 12 +- libclamav/dconf.h | 4 +- libclamav/filetypes.c | 13 +- libclamav/matcher-ac.c | 248 +--- libclamav/matcher-bm.c | 63 +- libclamav/matcher.h | 6 +- libclamav/mpool-2.1.0/ChangeLog.1 | 86 -- libclamav/mpool-2.1.0/Makefile | 56 - libclamav/mpool-2.1.0/NEWS | 11 - libclamav/mpool-2.1.0/README | 46 - libclamav/mpool-2.1.0/mpool.c | 1746 ----------------------------- libclamav/mpool-2.1.0/mpool.h | 466 -------- libclamav/mpool-2.1.0/mpool_loc.h | 116 -- libclamav/mpool-2.1.0/mpool_t.c | 914 --------------- libclamav/mpool.c | 253 +++++ libclamav/mpool.h | 62 + libclamav/phish_whitelist.c | 12 +- libclamav/phishcheck.c | 20 +- libclamav/readdb.c | 447 ++------ libclamav/regex_list.c | 55 +- libclamav/regex_list.h | 4 +- 21 files changed, 517 insertions(+), 4123 deletions(-) delete mode 100644 libclamav/mpool-2.1.0/ChangeLog.1 delete mode 100644 libclamav/mpool-2.1.0/Makefile delete mode 100644 libclamav/mpool-2.1.0/NEWS delete mode 100644 libclamav/mpool-2.1.0/README delete mode 100644 libclamav/mpool-2.1.0/mpool.c delete mode 100644 libclamav/mpool-2.1.0/mpool.h delete mode 100644 libclamav/mpool-2.1.0/mpool_loc.h delete mode 100644 libclamav/mpool-2.1.0/mpool_t.c create mode 100644 libclamav/mpool.c create mode 100644 libclamav/mpool.h diff --git a/libclamav/dconf.c b/libclamav/dconf.c index fe92aa72c..405743f98 100644 --- a/libclamav/dconf.c +++ b/libclamav/dconf.c @@ -35,9 +35,7 @@ #include "str.h" #include "others.h" -#ifdef USE_MPOOL #include "mpool.h" -#endif struct dconf_module { const char *mname; /* module name */ @@ -112,8 +110,8 @@ static struct dconf_module modules[] = { { NULL, NULL, 0, 0 } }; -#ifdef USE_MPOOL /* MPOOLFIXME : worthless? */ -struct cli_dconf *cli_dconf_init(mpool_t *mempool) +#ifdef USE_MPOOL +struct cli_dconf *cli_dconf_init(mp_t *mempool) #else struct cli_dconf *cli_dconf_init(void) #endif @@ -121,11 +119,7 @@ struct cli_dconf *cli_dconf_init(void) unsigned int i; struct cli_dconf *dconf; -#ifdef USE_MPOOL - dconf = (struct cli_dconf *) mpool_calloc(mempool, sizeof(struct cli_dconf), 1, NULL); -#else - dconf = (struct cli_dconf *) cli_calloc(sizeof(struct cli_dconf), 1); -#endif + dconf = (struct cli_dconf *) mp_calloc(mempool, sizeof(struct cli_dconf), 1); if(!dconf) return NULL; diff --git a/libclamav/dconf.h b/libclamav/dconf.h index 474673b8c..0884c0518 100644 --- a/libclamav/dconf.h +++ b/libclamav/dconf.h @@ -28,9 +28,7 @@ #include "cltypes.h" #include "cvd.h" -#ifdef USE_MPOOL #include "mpool.h" -#endif struct cli_dconf { uint32_t pe; @@ -101,7 +99,7 @@ struct cli_dconf { #define PHISHING_CONF_ENTCONV 0x2 #ifdef USE_MPOOL -struct cli_dconf *cli_dconf_init(mpool_t *); +struct cli_dconf *cli_dconf_init(mp_t *); #else struct cli_dconf *cli_dconf_init(void); #endif diff --git a/libclamav/filetypes.c b/libclamav/filetypes.c index 9a5ac3273..c5fda1496 100644 --- a/libclamav/filetypes.c +++ b/libclamav/filetypes.c @@ -40,6 +40,7 @@ #include "htmlnorm.h" #include "entconv.h" +#include "mpool.h" static const struct ftmap_s { const char *name; @@ -107,15 +108,9 @@ void cli_ftfree(const struct cl_engine *engine) while(ftypes) { pt = ftypes; ftypes = ftypes->next; -#ifdef USE_MPOOL - mpool_free(engine->mempool, pt->magic); - mpool_free(engine->mempool, pt->tname); - mpool_free(engine->mempool, pt); -#else - free(pt->magic); - free(pt->tname); - free(pt); -#endif + mp_free(engine->mempool, pt->magic); + mp_free(engine->mempool, pt->tname); + mp_free(engine->mempool, pt); } } diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c index 3215af89b..c67af153c 100644 --- a/libclamav/matcher-ac.c +++ b/libclamav/matcher-ac.c @@ -39,9 +39,7 @@ #include "str.h" #include "readdb.h" -#ifdef USE_MPOOL #include "mpool.h" -#endif uint8_t cli_ac_mindepth = AC_DEFAULT_MIN_DEPTH; uint8_t cli_ac_maxdepth = AC_DEFAULT_MAX_DEPTH; @@ -70,11 +68,7 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) for(i = 0; i < len; i++) { if(!pt->trans) { -#ifdef USE_MPOOL - pt->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *), NULL); -#else - pt->trans = (struct cli_ac_node **) cli_calloc(256, sizeof(struct cli_ac_node *)); -#endif + pt->trans = (struct cli_ac_node **) mp_calloc(root->mempool, 256, sizeof(struct cli_ac_node *)); if(!pt->trans) { cli_errmsg("cli_ac_addpatt: Can't allocate memory for pt->trans\n"); return CL_EMEM; @@ -84,29 +78,17 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) next = pt->trans[(unsigned char) (pattern->pattern[i] & 0xff)]; if(!next) { -#ifdef USE_MPOOL - next = (struct cli_ac_node *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_node), NULL); -#else - next = (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node)); -#endif + next = (struct cli_ac_node *) mp_calloc(root->mempool, 1, sizeof(struct cli_ac_node)); if(!next) { cli_errmsg("cli_ac_addpatt: Can't allocate memory for AC node\n"); return CL_EMEM; } if(i != len - 1) { -#ifdef USE_MPOOL - next->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *), NULL); -#else - next->trans = (struct cli_ac_node **) cli_calloc(256, sizeof(struct cli_ac_node *)); -#endif + next->trans = (struct cli_ac_node **) mp_calloc(root->mempool, 256, sizeof(struct cli_ac_node *)); if(!next->trans) { cli_errmsg("cli_ac_addpatt: Can't allocate memory for next->trans\n"); -#ifdef USE_MPOOL - mpool_free(root->mempool, next); -#else - free(next); -#endif + mp_free(root->mempool, next); return CL_EMEM; } } else { @@ -114,22 +96,13 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) } root->ac_nodes++; -#ifdef USE_MPOOL - newtable = mpool_resize(root->mempool, root->ac_nodetable, root->ac_nodes * sizeof(struct cli_ac_node *), NULL); -#else - newtable = cli_realloc(root->ac_nodetable, root->ac_nodes * sizeof(struct cli_ac_node *)); -#endif + newtable = mp_realloc(root->mempool, root->ac_nodetable, root->ac_nodes * sizeof(struct cli_ac_node *)); if(!newtable) { root->ac_nodes--; cli_errmsg("cli_ac_addpatt: Can't realloc ac_nodetable\n"); if(next->trans) -#ifdef USE_MPOOL - mpool_free(root->mempool, next->trans); - mpool_free(root->mempool, next); -#else - free(next->trans); - free(next); -#endif + mp_free(root->mempool, next->trans); + mp_free(root->mempool, next); return CL_EMEM; } root->ac_nodetable = (struct cli_ac_node **) newtable; @@ -143,11 +116,7 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) } root->ac_patterns++; -#ifdef USE_MPOOL - newtable = mpool_resize(root->mempool, root->ac_pattable, root->ac_patterns * sizeof(struct cli_ac_patt *), NULL); -#else - newtable = cli_realloc(root->ac_pattable, root->ac_patterns * sizeof(struct cli_ac_patt *)); -#endif + newtable = mp_realloc(root->mempool, root->ac_pattable, root->ac_patterns * sizeof(struct cli_ac_patt *)); if(!newtable) { root->ac_patterns--; cli_errmsg("cli_ac_addpatt: Can't realloc ac_pattable\n"); @@ -332,28 +301,16 @@ int cli_ac_buildtrie(struct cli_matcher *root) int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth) { -#ifdef USE_MPOOL - root->ac_root = (struct cli_ac_node *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_node), NULL); -#else - root->ac_root = (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node)); -#endif + root->ac_root = (struct cli_ac_node *) mp_calloc(root->mempool, 1, sizeof(struct cli_ac_node)); if(!root->ac_root) { cli_errmsg("cli_ac_init: Can't allocate memory for ac_root\n"); return CL_EMEM; } -#ifdef USE_MPOOL - root->ac_root->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *), NULL); -#else - root->ac_root->trans = (struct cli_ac_node **) cli_calloc(256, sizeof(struct cli_ac_node *)); -#endif + root->ac_root->trans = (struct cli_ac_node **) mp_calloc(root->mempool, 256, sizeof(struct cli_ac_node *)); if(!root->ac_root->trans) { cli_errmsg("cli_ac_init: Can't allocate memory for ac_root->trans\n"); -#ifdef USE_MPOOL - mpool_free(root->mempool, root->ac_root); -#else - free(root->ac_root); -#endif + mp_free(root->mempool, root->ac_root); return CL_EMEM; } @@ -364,7 +321,7 @@ int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth) } #ifdef USE_MPOOL -static void ac_free_alt(mpool_t *mempool, struct cli_ac_patt *p) +static void ac_free_alt(mp_t *mempool, struct cli_ac_patt *p) #else static void ac_free_alt(struct cli_ac_patt *p) #endif @@ -382,20 +339,11 @@ static void ac_free_alt(struct cli_ac_patt *p) a2 = a1; a1 = a1->next; if(a2->str) -#ifdef USE_MPOOL - mpool_free(mempool, a2->str); - mpool_free(mempool, a2); -#else - free(a2->str); - free(a2); -#endif + mp_free(mempool, a2->str); + mp_free(mempool, a2); } } -#ifdef USE_MPOOL - mpool_free(mempool, p->alttable); -#else - free(p->alttable); -#endif + mp_free(mempool, p->alttable); } void cli_ac_free(struct cli_matcher *root) @@ -406,67 +354,32 @@ void cli_ac_free(struct cli_matcher *root) for(i = 0; i < root->ac_patterns; i++) { patt = root->ac_pattable[i]; -#ifdef USE_MPOOL - patt->prefix ? mpool_free(root->mempool, patt->prefix) : mpool_free(root->mempool, patt->pattern); -#else - patt->prefix ? free(patt->prefix) : free(patt->pattern); -#endif -#ifdef USE_MPOOL - mpool_free(root->mempool, patt->virname); -#else - free(patt->virname); -#endif + mp_free(root->mempool, patt->prefix ? patt->prefix : patt->pattern); + mp_free(root->mempool, patt->virname); if(patt->offset) -#ifdef USE_MPOOL - mpool_free(root->mempool, patt->offset); -#else - free(patt->offset); -#endif + mp_free(root->mempool, patt->offset); if(patt->alt) #ifdef USE_MPOOL ac_free_alt(root->mempool, patt); #else ac_free_alt(patt); #endif -#ifdef USE_MPOOL - mpool_free(root->mempool, patt); - -#else - free(patt); -#endif + mp_free(root->mempool, patt); } if(root->ac_pattable) -#ifdef USE_MPOOL - mpool_free(root->mempool, root->ac_pattable); -#else - free(root->ac_pattable); -#endif + mp_free(root->mempool, root->ac_pattable); for(i = 0; i < root->ac_nodes; i++) { if(!root->ac_nodetable[i]->leaf) -#ifdef USE_MPOOL - mpool_free(root->mempool, root->ac_nodetable[i]->trans); - mpool_free(root->mempool, root->ac_nodetable[i]); -#else - free(root->ac_nodetable[i]->trans); - free(root->ac_nodetable[i]); -#endif + mp_free(root->mempool, root->ac_nodetable[i]->trans); + mp_free(root->mempool, root->ac_nodetable[i]); } if(root->ac_nodetable) -#ifdef USE_MPOOL - mpool_free(root->mempool, root->ac_nodetable); -#else - free(root->ac_nodetable); -#endif + mp_free(root->mempool, root->ac_nodetable); if(root->ac_root) { -#ifdef USE_MPOOL - mpool_free(root->mempool, root->ac_root->trans); - mpool_free(root->mempool, root->ac_root); -#else - free(root->ac_root->trans); - free(root->ac_root); -#endif + mp_free(root->mempool, root->ac_root->trans); + mp_free(root->mempool, root->ac_root); } } @@ -1189,11 +1102,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(strlen(hexsig) / 2 < root->ac_mindepth) return CL_EPATSHORT; -#ifdef USE_MPOOL - if((new = (struct cli_ac_patt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_patt), NULL)) == NULL) -#else - if((new = (struct cli_ac_patt *) cli_calloc(1, sizeof(struct cli_ac_patt))) == NULL) -#endif + if((new = (struct cli_ac_patt *) mp_calloc(root->mempool, 1, sizeof(struct cli_ac_patt))) == NULL) return CL_EMEM; new->rtype = rtype; @@ -1213,11 +1122,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(strchr(hexsig, '[')) { if(!(hexcpy = cli_strdup(hexsig))) { -#ifdef USE_MPOOL - mpool_free(root->mempool, new); -#else - free(new); -#endif + mp_free(root->mempool, new); return CL_EMEM; } @@ -1282,22 +1187,14 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(error) { free(hexcpy); -#ifdef USE_MPOOL - mpool_free(root->mempool, new); -#else - free(new); -#endif + mp_free(root->mempool, new); return error; } hex = cli_strdup(hex); free(hexcpy); if(!hex) { -#ifdef USE_MPOOL - mpool_free(root->mempool, new); -#else - free(new); -#endif + mp_free(root->mempool, new); return CL_EMEM; } } @@ -1308,11 +1205,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(hex) { hexcpy = hex; } else if(!(hexcpy = cli_strdup(hexsig))) { -#ifdef USE_MPOOL - mpool_free(root->mempool, new); -#else - free(new); -#endif + mp_free(root->mempool, new); return CL_EMEM; } @@ -1340,11 +1233,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex } *start++ = 0; -#ifdef USE_MPOOL - newalt = (struct cli_ac_alt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_alt), NULL); -#else - newalt = (struct cli_ac_alt *) cli_calloc(1, sizeof(struct cli_ac_alt)); -#endif + newalt = (struct cli_ac_alt *) mp_calloc(root->mempool, 1, sizeof(struct cli_ac_alt)); if(!newalt) { cli_errmsg("cli_ac_addsig: Can't allocate newalt\n"); error = CL_EMEM; @@ -1353,18 +1242,10 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex new->alt++; -#ifdef USE_MPOOL - newtable = (struct cli_ac_alt **) mpool_resize(root->mempool, new->alttable, new->alt * sizeof(struct cli_ac_alt *), NULL); -#else - newtable = (struct cli_ac_alt **) cli_realloc(new->alttable, new->alt * sizeof(struct cli_ac_alt *)); -#endif + newtable = (struct cli_ac_alt **) mp_realloc(root->mempool, new->alttable, new->alt * sizeof(struct cli_ac_alt *)); if(!newtable) { new->alt--; -#ifdef USE_MPOOL - mpool_free(root->mempool, newalt); -#else - free(newalt); -#endif + mp_free(root->mempool, newalt); cli_errmsg("cli_ac_addsig: Can't realloc new->alttable\n"); error = CL_EMEM; break; @@ -1384,11 +1265,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(3 * newalt->num - 1 == (uint16_t) strlen(pt)) { newalt->chmode = 1; -#ifdef USE_MPOOL - newalt->str = (unsigned char *) mpool_alloc(root->mempool, newalt->num, NULL); -#else - newalt->str = (unsigned char *) cli_malloc(newalt->num); -#endif + newalt->str = (unsigned char *) mp_malloc(root->mempool, newalt->num); if(!newalt->str) { cli_errmsg("cli_ac_addsig: Can't allocate newalt->str\n"); error = CL_EMEM; @@ -1417,11 +1294,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex while(altpt->next) altpt = altpt->next; -#ifdef USE_MPOOL - altpt->next = (struct cli_ac_alt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_alt), NULL); -#else - altpt->next = (struct cli_ac_alt *) cli_calloc(1, sizeof(struct cli_ac_alt)); -#endif + altpt->next = (struct cli_ac_alt *) mp_calloc(root->mempool, 1, sizeof(struct cli_ac_alt)); if(!altpt->next) { cli_errmsg("cli_ac_addsig: Can't allocate altpt->next\n"); error = CL_EMEM; @@ -1456,13 +1329,11 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex free(hex); #ifdef USE_MPOOL ac_free_alt(root->mempool, new); - } - mpool_free(root->mempool, new); #else ac_free_alt(new); - } - free(new); #endif + } + mp_free(root->mempool, new); return error; } } @@ -1472,7 +1343,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex unsigned int mpoolpattsz = (strlen(hex ? hex : hexsig) / 2 + 1) * sizeof(uint16_t); uint16_t *mpoolpatt = cli_hex2ui(hex ? hex : hexsig); if(mpoolpatt) { - if((new->pattern = mpool_alloc(root->mempool, mpoolpattsz, NULL)) != NULL) + if((new->pattern = mp_malloc(root->mempool, mpoolpattsz)) != NULL) memcpy(new->pattern, mpoolpatt, mpoolpattsz); free(mpoolpatt); } else new->pattern = NULL; @@ -1485,11 +1356,10 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(new->alt) #ifdef USE_MPOOL ac_free_alt(root->mempool, new); - mpool_free(root->mempool, new); #else ac_free_alt(new); - free(new); #endif + mp_free(root->mempool, new); free(hex); return CL_EMALFDB; } @@ -1539,13 +1409,11 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex cli_errmsg("cli_ac_addsig: Can't find a static subpattern of length %u\n", root->ac_mindepth); #ifdef USE_MPOOL ac_free_alt(root->mempool, new); - mpool_free(root->mempool, new->pattern); - mpool_free(root->mempool, new); #else ac_free_alt(new); - free(new->pattern); - free(new); #endif + mp_free(root->mempool, new->pattern); + mp_free(root->mempool, new); return CL_EMALFDB; } @@ -1566,7 +1434,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex { char *mpoolvirname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); if(mpoolvirname) { - if((new->virname = mpool_alloc(root->mempool, strlen(mpoolvirname) + 1, NULL)) != NULL) + if((new->virname = mp_malloc(root->mempool, strlen(mpoolvirname) + 1)) != NULL) strcpy(new->virname, mpoolvirname); free(mpoolvirname); } else new->virname = NULL; @@ -1575,15 +1443,13 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex new->virname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); #endif if(!new->virname) { + mp_free(root->mempool, new->prefix ? new->prefix : new->pattern); #ifdef USE_MPOOL - new->prefix ? mpool_free(root->mempool, new->prefix) : mpool_free(root->mempool, new->pattern); ac_free_alt(root->mempool, new); - mpool_free(root->mempool, new); #else - new->prefix ? free(new->prefix) : free(new->pattern); ac_free_alt(new); - free(new); #endif + mp_free(root->mempool, new); return CL_EMEM; } @@ -1592,43 +1458,35 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if(offset) { #ifdef USE_MPOOL - if((new->offset = mpool_alloc(root->mempool, strlen(offset) + 1, NULL))) + if((new->offset = mp_malloc(root->mempool, strlen(offset) + 1))) strcpy(new->offset, offset); #else new->offset = cli_strdup(offset); #endif if(!new->offset) { + mp_free(root->mempool, new->prefix ? new->prefix : new->pattern); #ifdef USE_MPOOL - new->prefix ? mpool_free(root->mempool, new->prefix) : mpool_free(root->mempool, new->pattern); ac_free_alt(root->mempool, new); - mpool_free(root->mempool, new->virname); - mpool_free(root->mempool, new); #else - new->prefix ? free(new->prefix) : free(new->pattern); ac_free_alt(new); - free(new->virname); - free(new); #endif + mp_free(root->mempool, new->virname); + mp_free(root->mempool, new); return CL_EMEM; } } if((ret = cli_ac_addpatt(root, new))) { + mp_free(root->mempool, new->prefix ? new->prefix : new->pattern); + mp_free(root->mempool, new->virname); #ifdef USE_MPOOL - new->prefix ? mpool_free(root->mempool, new->prefix) : mpool_free(root->mempool, new->pattern); - mpool_free(root->mempool, new->virname); ac_free_alt(root->mempool, new); - if(new->offset) - mpool_free(root->mempool, new->offset); - mpool_free(root->mempool, new); #else - new->prefix ? free(new->prefix) : free(new->pattern); - free(new->virname); ac_free_alt(new); - if(new->offset) - free(new->offset); - free(new); #endif + if(new->offset) + mp_free(root->mempool, new->offset); + mp_free(root->mempool, new); return ret; } diff --git a/libclamav/matcher-bm.c b/libclamav/matcher-bm.c index 974507a8f..a0544632d 100644 --- a/libclamav/matcher-bm.c +++ b/libclamav/matcher-bm.c @@ -32,9 +32,7 @@ #include "matcher-bm.h" #include "filetypes.h" -#ifdef USE_MPOOL #include "mpool.h" -#endif #define BM_MIN_LENGTH 3 #define BM_BLOCK_SIZE 3 @@ -101,23 +99,11 @@ int cli_bm_init(struct cli_matcher *root) { uint16_t i, size = HASH(255, 255, 255) + 1; -#ifdef USE_MPOOL - if(!(root->bm_shift = (uint8_t *) mpool_calloc(root->mempool, size, sizeof(uint8_t), NULL))) -#else - if(!(root->bm_shift = (uint8_t *) cli_calloc(size, sizeof(uint8_t)))) -#endif + if(!(root->bm_shift = (uint8_t *) mp_calloc(root->mempool, size, sizeof(uint8_t)))) return CL_EMEM; -#ifdef USE_MPOOL - if(!(root->bm_suffix = (struct cli_bm_patt **) mpool_calloc(root->mempool, size, sizeof(struct cli_bm_patt *), NULL))) { -#else - if(!(root->bm_suffix = (struct cli_bm_patt **) cli_calloc(size, sizeof(struct cli_bm_patt *)))) { -#endif -#ifdef USE_MPOOL - mpool_free(root->mempool, root->bm_shift); -#else - free(root->bm_shift); -#endif + if(!(root->bm_suffix = (struct cli_bm_patt **) mp_calloc(root->mempool, size, sizeof(struct cli_bm_patt *)))) { + mp_free(root->mempool, root->bm_shift); return CL_EMEM; } @@ -134,11 +120,7 @@ void cli_bm_free(struct cli_matcher *root) if(root->bm_shift) -#ifdef USE_MPOOL - mpool_free(root->mempool, root->bm_shift); -#else - free(root->bm_shift); -#endif + mp_free(root->mempool, root->bm_shift); if(root->bm_suffix) { for(i = 0; i < size; i++) { @@ -147,42 +129,17 @@ void cli_bm_free(struct cli_matcher *root) prev = patt; patt = patt->next; if(prev->prefix) -#ifdef USE_MPOOL - mpool_free(root->mempool, prev->prefix); -#else - free(prev->prefix); -#endif + mp_free(root->mempool, prev->prefix); else -#ifdef USE_MPOOL - mpool_free(root->mempool, prev->pattern); -#else - free(prev->pattern); -#endif + mp_free(root->mempool, prev->pattern); if(prev->virname) -#ifdef USE_MPOOL - mpool_free(root->mempool, prev->virname); -#else - free(prev->virname); -#endif + mp_free(root->mempool, prev->virname); if(prev->offset) -#ifdef USE_MPOOL - mpool_free(root->mempool, prev->offset); -#else - free(prev->offset); -#endif -#ifdef USE_MPOOL - mpool_free(root->mempool, prev); -#else - free(prev); -#endif - + mp_free(root->mempool, prev->offset); + mp_free(root->mempool, prev); } } -#ifdef USE_MPOOL - mpool_free(root->mempool, root->bm_suffix); -#else - free(root->bm_suffix); -#endif + mp_free(root->mempool, root->bm_suffix); } } diff --git a/libclamav/matcher.h b/libclamav/matcher.h index 44cd2e89f..891731d97 100644 --- a/libclamav/matcher.h +++ b/libclamav/matcher.h @@ -34,9 +34,7 @@ #include "matcher-bm.h" #include "hashtab.h" -#ifdef USE_MPOOL #include "mpool.h" -#endif #define CLI_MATCH_WILDCARD 0xff00 #define CLI_MATCH_CHAR 0x0000 @@ -59,7 +57,7 @@ struct cli_lsig_tdb { const uint32_t *sectoff, *sectrva, *sectvsz, *sectraw, *sectrsz, *secturva, *sectuvsz, *secturaw, *sectursz; #ifdef USE_MPOOL - mpool_t *mempool; + mp_t *mempool; #endif }; @@ -88,7 +86,7 @@ struct cli_matcher { uint16_t maxpatlen; uint8_t ac_only; #ifdef USE_MPOOL - mpool_t *mempool; + mp_t *mempool; #endif }; diff --git a/libclamav/mpool-2.1.0/ChangeLog.1 b/libclamav/mpool-2.1.0/ChangeLog.1 deleted file mode 100644 index 40c4a53ee..000000000 --- a/libclamav/mpool-2.1.0/ChangeLog.1 +++ /dev/null @@ -1,86 +0,0 @@ -2006-05-31 Gray Watson <> - - * Version 2.1.0 released. - - * Added MPOOL_ERROR_PNT_OVER to distinguish between pointer - overwrite and mpool structure overwrite. - -2005-05-20 Gray Watson <> - - * Version 2.0.0 released. - - * First external publication of library. - -Thu Mar 4 10:14:21 1999 Gray Watson <> - - * Reworked the way the blocks were split up. - - * Removed the round arguments. Not used. - -Wed Mar 3 19:29:38 1999 Gray Watson <> - - * Moved to random(). Fucking rand() was hiding a lot of problems - from me. - - * Added some additional sanity checks in free(). - - * Added mpool_set_max_pages to the library. - -Thu Feb 25 12:41:51 1999 Gray Watson <> - - * Added log_function transaction callback. - -Thu Feb 25 09:53:33 1999 Gray Watson <> - - * Changed the default page size to 16 * getpagesize. - -Wed Feb 24 17:52:52 1999 Gray Watson <> - - * Major reworking of internals to simplify structures. - -Fri Feb 19 12:52:55 1999 Gray Watson <> - - * Made a number of changes to the internals which removed the - addr_to_block as a performance pig. - -Tue Feb 16 21:11:23 1999 Gray Watson <> - - * Added ability for free to look up in the free bit lists for - memory to use. - - * Added mpool_clear. Good idea. - -Thu Feb 11 02:53:45 1999 Gray Watson <> - - * Finally a working version. Looks much better. - - * Added rounding sizes so it will allocate aligned memory. - - * Added minimum size to the mpool_free function to speed it up. - -Wed Feb 10 23:30:48 1999 Gray Watson <> - - * Version 1 with new fine grained memory resolution almost - working. - -Fri May 2 02:26:28 1997 Gray Watson <> - - * Moved to MAP_PRIVATE from MAP_SHARED. - - * Fixed the min/max handling. - - * Added additional info to mpool_stat. - -Thu May 1 16:51:06 1997 Gray Watson <> - - * Added page-size information request. - - * Added better no-memory errors. - -Thu Apr 24 01:58:41 1997 Gray Watson <> - - * Added handling of null for debugging purposes. - -Mon Apr 14 03:31:26 1997 Gray Watson <> - - * Started the mpool routines. diff --git a/libclamav/mpool-2.1.0/Makefile b/libclamav/mpool-2.1.0/Makefile deleted file mode 100644 index fd34e311b..000000000 --- a/libclamav/mpool-2.1.0/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# $Id: Makefile.all,v 1.1.1.1 2005/05/20 19:58:29 gray Exp $ -# - -HFLS = mpool.h -OBJS = mpool.o - -CC = cc - -CFLAGS = -g -I. $(DEFINES) -#CFLAGS = -g -I. -LDFLAGS = -RANLIB = ranlib - -DESTDIR = /usr/local -TEST = mpool_t -LIBRARY = libmpool.a - -all : $(LIBRARY) $(UTIL) - -clean : - rm -f a.out core *.o *.t - rm -f $(LIBRARY) $(TEST) - -install : $(HFLS) $(LIBRARY) - install -c -m 444 $(HFLS) $(DESTDIR)/include - install -c -m 444 $(LIBRARY) $(DESTDIR)/lib - $(RANLIB) $(DESTDIR)/libo/$(LIBRARY) - -$(LIBRARY) : $(OBJS) - ar cr $(LIBRARY) $? - $(RANLIB) $@ - -tests : $(TEST) - -$(TEST) : $(TEST).o $(LIBRARY) - rm -f $@ - $(CC) $(LDFLAGS) $(TEST).o $(LIBRARY) - mv a.out $@ - -$(UTIL) : $(UTIL).o $(LIBRARY) - rm -f $@ - $(CC) $(LDFLAGS) $(UTIL).o $(LIBRARY) - mv a.out $@ - -.c.o : - rm -f $@ - $(CC) $(CFLAGS) -c $< -o $@ - -# -# Below are dependencies that are automatically generated by make -# depend. Please do not edit by hand. -# - -mpool.o: mpool.c mpool.h mpool_loc.h -mpool_t.o: mpool_t.c mpool.h diff --git a/libclamav/mpool-2.1.0/NEWS b/libclamav/mpool-2.1.0/NEWS deleted file mode 100644 index f6c0ab2a1..000000000 --- a/libclamav/mpool-2.1.0/NEWS +++ /dev/null @@ -1,11 +0,0 @@ -------------------------------------------------------------------------------- -$Id: NEWS,v 1.2 2006/05/31 20:28:31 gray Exp $ -------------------------------------------------------------------------------- - -Version 2.1.0: - - * Added MPOOL_ERROR_PNT_OVER to show pointer overwrites. - -Version 2.0.0: - - * Initial external release of library after use since 1996. diff --git a/libclamav/mpool-2.1.0/README b/libclamav/mpool-2.1.0/README deleted file mode 100644 index 7277ff2ad..000000000 --- a/libclamav/mpool-2.1.0/README +++ /dev/null @@ -1,46 +0,0 @@ -------------------------------------------------------------------------------- -$Id: README,v 1.2 2005/05/22 19:49:30 gray Exp $ -------------------------------------------------------------------------------- - -BACKGROUND: - -This is a memory pool library which was written to allow a program to -have heaps that it could destroy without fragmenting memory. You can -have multiple heaps and reset them easily completely reclaiming the -memory (as opposed to standard heaps). - -With it you can mpool_open() a new heap, then mpool_alloc(), -mpool_calloc(), mpool_realloc(), mpool_free() to your heart's content. -Once you are done with the memory-pool you can run mpool_clear() or -mpool_close() and completely remove the memory associated with the -pools. This is very handy if you are working with some large blocks -of memory and want to reset back to a clean state. - -Check out the mpool.h file for more information. Sorry for minimal -docs. - -------------------------------------------------------------------------------- - -INSTALLATION: - -1) Typing 'make' should be enough to build libskip.a. -2) Typing 'make tests' should make the mpool_t test program. - -------------------------------------------------------------------------------- - -REPOSITORY: - -The newest versions of the library are available from: - - http://256.com/sources/mpool/ - -------------------------------------------------------------------------------- - -AUTHOR: - -If you have any questions or problems feel free to send me mail. - -Gray Watson -http://256.com/gray/ - -------------------------------------------------------------------------------- diff --git a/libclamav/mpool-2.1.0/mpool.c b/libclamav/mpool-2.1.0/mpool.c deleted file mode 100644 index 12eac5374..000000000 --- a/libclamav/mpool-2.1.0/mpool.c +++ /dev/null @@ -1,1746 +0,0 @@ -/* - * Memory pool routines. - * - * Copyright 1996 by Gray Watson. - * - * This file is part of the mpool package. - * - * Permission to use, copy, modify, and distribute this software for - * any purpose and without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies, and that the name of Gray Watson not be used in advertising - * or publicity pertaining to distribution of the document or software - * without specific, written prior permission. - * - * Gray Watson makes no representations about the suitability of the - * software described herein for any purpose. It is provided "as is" - * without express or implied warranty. - * - * The author may be reached via http://256.com/gray/ - * - * $Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $ - */ - -/* - * Memory-pool allocation routines. I got sick of the GNU mmalloc - * library which was close to what we needed but did not exactly do - * what I wanted. - * - * The following uses mmap from /dev/zero. It allows a number of - * allocations to be made inside of a memory pool then with a clear or - * close the pool can be reset without any memory fragmentation and - * growth problems. - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef DMALLOC -#include "dmalloc.h" -#endif - -#define MPOOL_MAIN - -#include "mpool.h" -#include "mpool_loc.h" - -#ifdef __GNUC__ -#ident "$Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $" -#else -static char *rcs_id = "$Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $"; -#endif - -/* ACAB */ -#include -struct FRAG { - unsigned long frag_size; - void *frag_ptr; -}; -#define FRAG_OVERHEAD (offsetof(struct FRAG, frag_ptr)) - -/* version */ -static char *version = "mpool library version 2.1.0"; - -/* local variables */ -static int enabled_b = 0; /* lib initialized? */ -static unsigned int min_bit_free_next = 0; /* min size of next pnt */ -static unsigned int min_bit_free_size = 0; /* min size of next + size */ -static unsigned long bit_array[MAX_BITS + 1]; /* size -> bit */ - -/****************************** local utilities ******************************/ - -/* - * static void startup - * - * DESCRIPTION: - * - * Perform any library level initialization. - * - * RETURNS: - * - * None. - * - * ARGUMENTS: - * - * None. - */ -static void startup(void) -{ - int bit_c; - unsigned long size = 1; - - if (enabled_b) { - return; - } - - /* allocate our free bit array list */ - for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { - bit_array[bit_c] = size; - - /* - * Note our minimum number of bits that can store a pointer. This - * is smallest address that we can have a linked list for. - */ - if (min_bit_free_next == 0 && size >= sizeof(void *)) { - min_bit_free_next = bit_c; - } - /* - * Note our minimum number of bits that can store a pointer and - * the size of the block. - */ - if (min_bit_free_size == 0 && size >= sizeof(mpool_free_t)) { - min_bit_free_size = bit_c; - } - - size *= 2; - } - - enabled_b = 1; -} - -/* - * static int size_to_bits - * - * DESCRIPTION: - * - * Calculate the number of bits in a size. - * - * RETURNS: - * - * Number of bits. - * - * ARGUMENTS: - * - * size -> Size of memory of which to calculate the number of bits. - */ -static int size_to_bits(const unsigned long size) -{ - int bit_c = 0; - - for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { - if (size <= bit_array[bit_c]) { - break; - } - } - - return bit_c; -} - -/* - * static int size_to_free_bits - * - * DESCRIPTION: - * - * Calculate the number of bits in a size going on the free list. - * - * RETURNS: - * - * Number of bits. - * - * ARGUMENTS: - * - * size -> Size of memory of which to calculate the number of bits. - */ -static int size_to_free_bits(const unsigned long size) -{ - int bit_c = 0; - - if (size == 0) { - return 0; - } - - for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { - if (size < bit_array[bit_c]) { - break; - } - } - - return bit_c - 1; -} - -/* - * static int bits_to_size - * - * DESCRIPTION: - * - * Calculate the size represented by a number of bits. - * - * RETURNS: - * - * Number of bits. - * - * ARGUMENTS: - * - * bit_n -> Number of bits - */ -static unsigned long bits_to_size(const int bit_n) -{ - if (bit_n > MAX_BITS) { - return bit_array[MAX_BITS]; - } - else { - return bit_array[bit_n]; - } -} - -/* - * static void *alloc_pages - * - * DESCRIPTION: - * - * Allocate space for a number of memory pages in the memory pool. - * - * RETURNS: - * - * Success - New pages of memory - * - * Failure - NULL - * - * ARGUMENTS: - * - * mp_p <-> Pointer to our memory pool. - * - * page_n -> Number of pages to alloc. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -static void *alloc_pages(mpool_t *mp_p, const unsigned int page_n, - int *error_p) -{ - void *mem, *fill_mem; - unsigned long size, fill; - int state; - - /* are we over our max-pages? */ - if (mp_p->mp_max_pages > 0 && mp_p->mp_page_c >= mp_p->mp_max_pages) { - SET_POINTER(error_p, MPOOL_ERROR_NO_PAGES); - return NULL; - } - - size = SIZE_OF_PAGES(mp_p, page_n); - -#ifdef DEBUG - (void)printf("allocating %u pages or %lu bytes\n", page_n, size); -#endif - - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) { - mem = sbrk(size); - if (mem == (void *)-1) { - SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); - return NULL; - } - fill = (unsigned long)mem % mp_p->mp_page_size; - - if (fill > 0) { - fill = mp_p->mp_page_size - fill; - fill_mem = sbrk(fill); - if (fill_mem == (void *)-1) { - SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); - return NULL; - } - if ((char *)fill_mem != (char *)mem + size) { - SET_POINTER(error_p, MPOOL_ERROR_SBRK_CONTIG); - return NULL; - } - mem = (char *)mem + fill; - } - } - else { - state = MAP_PRIVATE; -#ifdef MAP_FILE - state |= MAP_FILE; -#endif -#ifdef MAP_VARIABLE - state |= MAP_VARIABLE; -#endif - - /* mmap from /dev/zero */ - mem = mmap((caddr_t)mp_p->mp_addr, size, PROT_READ | PROT_WRITE, state, - mp_p->mp_fd, mp_p->mp_top); - if (mem == (void *)MAP_FAILED) { - if (errno == ENOMEM) { - SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); - } - else { - SET_POINTER(error_p, MPOOL_ERROR_MMAP); - } - return NULL; - } - mp_p->mp_top += size; - if (mp_p->mp_addr != NULL) { - mp_p->mp_addr = (char *)mp_p->mp_addr + size; - } - } - - mp_p->mp_page_c += page_n; - - SET_POINTER(error_p, MPOOL_ERROR_NONE); - return mem; -} - -/* - * static int free_pages - * - * DESCRIPTION: - * - * Free previously allocated pages of memory. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * pages <-> Pointer to memory pages that we are freeing. - * - * size -> Size of the block that we are freeing. - * - * sbrk_b -> Set to one if the pages were allocated with sbrk else mmap. - */ -static int free_pages(void *pages, const unsigned long size, - const int sbrk_b) -{ - if (! sbrk_b) { - (void)munmap((caddr_t)pages, size); - } - - return MPOOL_ERROR_NONE; -} - -/* - * static int check_magic - * - * DESCRIPTION: - * - * Check for the existance of the magic ID in a memory pointer. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * addr -> Address inside of the block that we are tryign to locate. - * - * size -> Size of the block. - */ -static int check_magic(const void *addr, const unsigned long size) -{ - const unsigned char *mem_p; - - /* set our starting point */ - mem_p = (unsigned char *)addr + size; - - if (*mem_p == FENCE_MAGIC0 && *(mem_p + 1) == FENCE_MAGIC1) { - return MPOOL_ERROR_NONE; - } - else { - return MPOOL_ERROR_PNT_OVER; - } -} - -/* - * static void write_magic - * - * DESCRIPTION: - * - * Write the magic ID to the address. - * - * RETURNS: - * - * None. - * - * ARGUMENTS: - * - * addr -> Address where to write the magic. - */ -static void write_magic(const void *addr) -{ - *(unsigned char *)addr = FENCE_MAGIC0; - *((unsigned char *)addr + 1) = FENCE_MAGIC1; -} - -/* - * static void free_pointer - * - * DESCRIPTION: - * - * Moved a pointer into our free lists. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. - * - * addr <-> Address where to write the magic. We may write a next - * pointer to it. - * - * size -> Size of the address space. - */ -static int free_pointer(mpool_t *mp_p, void *addr, - const unsigned long size) -{ - unsigned int bit_n; - unsigned long real_size; - mpool_free_t free_pnt; - -#ifdef DEBUG - (void)printf("freeing a block at %lx of %lu bytes\n", (long)addr, size); -#endif - - if (size == 0) { - return MPOOL_ERROR_NONE; - } - - /* - * if the user size is larger then can fit in an entire block then - * we change the size - */ - if (size > MAX_BLOCK_USER_MEMORY(mp_p)) { - real_size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, size)) - - sizeof(mpool_block_t); - } - else { - real_size = size; - } - - /* - * We use a specific free bits calculation here because if we are - * freeing 10 bytes then we will be putting it into the 8-byte free - * list and not the 16 byte list. size_to_bits(10) will return 4 - * instead of 3. - */ - bit_n = size_to_free_bits(real_size); - - /* - * Minimal error checking. We could go all the way through the - * list however this might be prohibitive. - */ - if (mp_p->mp_free[bit_n] == addr) { - return MPOOL_ERROR_IS_FREE; - } - - /* add the freed pointer to the free list */ - if (bit_n < min_bit_free_next) { - /* - * Yes we know this will lose 99% of the allocations but what else - * can we do? No space for a next pointer. - */ - if (mp_p->mp_free[bit_n] == NULL) { - mp_p->mp_free[bit_n] = addr; - } - } - else if (bit_n < min_bit_free_size) { - /* we copy, not assign, to maintain the free list */ - memcpy(addr, mp_p->mp_free + bit_n, sizeof(void *)); - mp_p->mp_free[bit_n] = addr; - } - else { - - /* setup our free list structure */ - free_pnt.mf_next_p = mp_p->mp_free[bit_n]; - free_pnt.mf_size = real_size; - - /* we copy the structure in since we don't know about alignment */ - memcpy(addr, &free_pnt, sizeof(free_pnt)); - mp_p->mp_free[bit_n] = addr; - } - - return MPOOL_ERROR_NONE; -} - -/* - * static int split_block - * - * DESCRIPTION: - * - * When freeing space in a multi-block chunk we have to create new - * blocks out of the upper areas being freed. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. - * - * free_addr -> Address that we are freeing. - * - * size -> Size of the space that we are taking from address. - */ -static int split_block(mpool_t *mp_p, void *free_addr, - const unsigned long size) -{ - mpool_block_t *block_p, *new_block_p; - int ret, page_n; - void *end_p; - - /* - * 1st we find the block pointer from our free addr. At this point - * the pointer must be the 1st one in the block if it is spans - * multiple blocks. - */ - block_p = (mpool_block_t *)((char *)free_addr - sizeof(mpool_block_t)); - if (block_p->mb_magic != BLOCK_MAGIC - || block_p->mb_magic2 != BLOCK_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - - page_n = PAGES_IN_SIZE(mp_p, size); - - /* we are creating a new block structure for the 2nd ... */ - new_block_p = (mpool_block_t *)((char *)block_p + - SIZE_OF_PAGES(mp_p, page_n)); - new_block_p->mb_magic = BLOCK_MAGIC; - /* New bounds is 1st block bounds. The 1st block's is reset below. */ - new_block_p->mb_bounds_p = block_p->mb_bounds_p; - /* Continue the linked list. The 1st block will point to us below. */ - new_block_p->mb_next_p = block_p->mb_next_p; - new_block_p->mb_magic2 = BLOCK_MAGIC; - - /* bounds for the 1st block are reset to the 1st page only */ - block_p->mb_bounds_p = (char *)new_block_p; - /* the next block pointer for the 1st block is now the new one */ - block_p->mb_next_p = new_block_p; - - /* only free the space in the 1st block if it is only 1 block in size */ - if (page_n == 1) { - /* now free the rest of the 1st block block */ - end_p = (char *)free_addr + size; - ret = free_pointer(mp_p, end_p, - (char *)block_p->mb_bounds_p - (char *)end_p); - if (ret != MPOOL_ERROR_NONE) { - return ret; - } - } - - /* now free the rest of the block */ - ret = free_pointer(mp_p, FIRST_ADDR_IN_BLOCK(new_block_p), - MEMORY_IN_BLOCK(new_block_p)); - if (ret != MPOOL_ERROR_NONE) { - return ret; - } - - return MPOOL_ERROR_NONE; -} - -/* - * static void *get_space - * - * DESCRIPTION: - * - * Moved a pointer into our free lists. - * - * RETURNS: - * - * Success - New address that we can use. - * - * Failure - NULL - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. - * - * byte_size -> Size of the address space that we need. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -static void *get_space(mpool_t *mp_p, const unsigned long byte_size, - int *error_p) -{ - mpool_block_t *block_p; - mpool_free_t free_pnt; - int ret; - unsigned long size; - unsigned int bit_c, page_n, left; - void *free_addr = NULL, *free_end; - - size = byte_size; - while ((size & (sizeof(void *) - 1)) > 0) { - size++; - } - - /* - * First we check the free lists looking for something with enough - * pages. Maybe we should only look X bits higher in the list. - * - * XXX: this is where we'd do the best fit. We'd look for the - * closest match. We then could put the rest of the allocation that - * we did not use in a lower free list. Have a define which states - * how deep in the free list to go to find the closest match. - */ - for (bit_c = size_to_bits(size); bit_c <= MAX_BITS; bit_c++) { - if (mp_p->mp_free[bit_c] != NULL) { - free_addr = mp_p->mp_free[bit_c]; - break; - } - } - - /* - * If we haven't allocated any blocks or if the last block doesn't - * have enough memory then we need a new block. - */ - if (bit_c > MAX_BITS) { - - /* we need to allocate more space */ - - page_n = PAGES_IN_SIZE(mp_p, size); - - /* now we try and get the pages we need/want */ - block_p = alloc_pages(mp_p, page_n, error_p); - if (block_p == NULL) { - /* error_p set in alloc_pages */ - return NULL; - } - - /* init the block header */ - block_p->mb_magic = BLOCK_MAGIC; - block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(mp_p, page_n); - block_p->mb_next_p = mp_p->mp_first_p; - block_p->mb_magic2 = BLOCK_MAGIC; - - /* - * We insert it into the front of the queue. We could add it to - * the end but there is not much use. - */ - mp_p->mp_first_p = block_p; - if (mp_p->mp_last_p == NULL) { - mp_p->mp_last_p = block_p; - } - - free_addr = FIRST_ADDR_IN_BLOCK(block_p); - -#ifdef DEBUG - (void)printf("had to allocate space for %lx of %lu bytes\n", - (long)free_addr, size); -#endif - - free_end = (char *)free_addr + size; - left = (char *)block_p->mb_bounds_p - (char *)free_end; - } - else { - - if (bit_c < min_bit_free_next) { - mp_p->mp_free[bit_c] = NULL; - /* calculate the number of left over bytes */ - left = bits_to_size(bit_c) - size; - } - else if (bit_c < min_bit_free_next) { - /* grab the next pointer from the freed address into our list */ - memcpy(mp_p->mp_free + bit_c, free_addr, sizeof(void *)); - /* calculate the number of left over bytes */ - left = bits_to_size(bit_c) - size; - } - else { - /* grab the free structure from the address */ - memcpy(&free_pnt, free_addr, sizeof(free_pnt)); - mp_p->mp_free[bit_c] = free_pnt.mf_next_p; - - /* are we are splitting up a multiblock chunk into fewer blocks? */ - if (PAGES_IN_SIZE(mp_p, free_pnt.mf_size) > PAGES_IN_SIZE(mp_p, size)) { - ret = split_block(mp_p, free_addr, size); - if (ret != MPOOL_ERROR_NONE) { - SET_POINTER(error_p, ret); - return NULL; - } - /* left over memory was taken care of in split_block */ - left = 0; - } - else { - /* calculate the number of left over bytes */ - left = free_pnt.mf_size - size; - } - } - -#ifdef DEBUG - (void)printf("found a free block at %lx of %lu bytes\n", - (long)free_addr, left + size); -#endif - - free_end = (char *)free_addr + size; - } - - /* - * If we have memory left over then we free it so someone else can - * use it. We do not free the space if we just allocated a - * multi-block chunk because we need to have every allocation easily - * find the start of the block. Every user address % page-size - * should take us to the start of the block. - */ - if (left > 0 && size <= MAX_BLOCK_USER_MEMORY(mp_p)) { - /* free the rest of the block */ - ret = free_pointer(mp_p, free_end, left); - if (ret != MPOOL_ERROR_NONE) { - SET_POINTER(error_p, ret); - return NULL; - } - } - - /* update our bounds */ - if (free_addr > mp_p->mp_bounds_p) { - mp_p->mp_bounds_p = free_addr; - } - else if (free_addr < mp_p->mp_min_p) { - mp_p->mp_min_p = free_addr; - } - - return free_addr; -} - -/* - * static void *alloc_mem - * - * DESCRIPTION: - * - * Allocate space for bytes inside of an already open memory pool. - * - * RETURNS: - * - * Success - Pointer to the address to use. - * - * Failure - NULL - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. If NULL then it will do a - * normal malloc. - * - * byte_size -> Number of bytes to allocate in the pool. Must be >0. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -static void *alloc_mem(mpool_t *mp_p, const unsigned long byte_size, - int *error_p) -{ - unsigned long size, fence; - void *addr; - - /* make sure we have enough bytes */ - if (byte_size < MIN_ALLOCATION) { - size = MIN_ALLOCATION; - } - else { - size = byte_size; - } - - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { - fence = 0; - } - else { - fence = FENCE_SIZE; - } - - /* get our free space + the space for the fence post */ - addr = get_space(mp_p, size + fence, error_p); - if (addr == NULL) { - /* error_p set in get_space */ - return NULL; - } - - if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { - write_magic((char *)addr + size); - } - - /* maintain our stats */ - mp_p->mp_alloc_c++; - mp_p->mp_user_alloc += size; - if (mp_p->mp_user_alloc > mp_p->mp_max_alloc) { - mp_p->mp_max_alloc = mp_p->mp_user_alloc; - } - - SET_POINTER(error_p, MPOOL_ERROR_NONE); - // printf("^alloc'd %p::%p(%u)\n", mp_p, addr, byte_size); - return addr; -} - -/* - * static int free_mem - * - * DESCRIPTION: - * - * Free an address from a memory pool. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. If NULL then it will do a - * normal free. - * - * addr <-> Address to free. - * - * size -> Size of the address being freed. - */ -static int free_mem(mpool_t *mp_p, void *addr, const unsigned long size) -{ - unsigned long old_size, fence; - int ret; - mpool_block_t *block_p; - - // printf("free'd %p::%p(%u)\n", mp_p, addr, size); - - /* - * If the size is larger than a block then the allocation must be at - * the front of the block. - */ - if (size > MAX_BLOCK_USER_MEMORY(mp_p)) { - block_p = (mpool_block_t *)((char *)addr - sizeof(mpool_block_t)); - if (block_p->mb_magic != BLOCK_MAGIC - || block_p->mb_magic2 != BLOCK_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - } - - /* make sure we have enough bytes */ - if (size < MIN_ALLOCATION) { - old_size = MIN_ALLOCATION; - } - else { - old_size = size; - } - - /* if we are packing the pool smaller */ - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { - fence = 0; - } - else { - /* find the user's magic numbers if they were written */ - ret = check_magic(addr, old_size); - if (ret != MPOOL_ERROR_NONE) { - return ret; - } - fence = FENCE_SIZE; - } - - /* now we free the pointer */ - ret = free_pointer(mp_p, addr, old_size + fence); - if (ret != MPOOL_ERROR_NONE) { - return ret; - } - mp_p->mp_user_alloc -= old_size; - - /* adjust our stats */ - mp_p->mp_alloc_c--; - return MPOOL_ERROR_NONE; -} - -/***************************** exported routines *****************************/ - -/* - * mpool_t *mpool_open - * - * DESCRIPTION: - * - * Open/allocate a new memory pool. - * - * RETURNS: - * - * Success - Pool pointer which must be passed to mpool_close to - * deallocate. - * - * Failure - NULL - * - * ARGUMENTS: - * - * flags -> Flags to set attributes of the memory pool. See the top - * of mpool.h. - * - * page_size -> Set the internal memory page-size. This must be a - * multiple of the getpagesize() value. Set to 0 for the default. - * - * start_addr -> Starting address to try and allocate memory pools. - * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, - void *start_addr, int *error_p) -{ - mpool_block_t *block_p; - int page_n, ret; - mpool_t mp, *mp_p; - void *free_addr; - - if (! enabled_b) { - startup(); - } - - /* zero our temp struct */ - memset(&mp, 0, sizeof(mp)); - - mp.mp_magic = MPOOL_MAGIC; - mp.mp_flags = flags; - mp.mp_alloc_c = 0; - mp.mp_user_alloc = 0; - mp.mp_max_alloc = 0; - mp.mp_page_c = 0; - /* mp.mp_page_size set below */ - /* mp.mp_blocks_bit_n set below */ - /* mp.mp_fd set below */ - /* mp.mp_top set below */ - /* mp.mp_addr set below */ - mp.mp_log_func = NULL; - mp.mp_min_p = NULL; - mp.mp_bounds_p = NULL; - mp.mp_first_p = NULL; - mp.mp_last_p = NULL; - mp.mp_magic2 = MPOOL_MAGIC; - - /* get and sanity check our page size */ - if (page_size > 0) { - mp.mp_page_size = page_size; - if (mp.mp_page_size % getpagesize() != 0) { - SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); - return NULL; - } - } - else { - mp.mp_page_size = getpagesize() * DEFAULT_PAGE_MULT; - if (mp.mp_page_size % 1024 != 0) { - SET_POINTER(error_p, MPOOL_ERROR_PAGE_SIZE); - return NULL; - } - } - - if (BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)) { - mp.mp_fd = -1; - mp.mp_addr = NULL; - mp.mp_top = 0; - } - else { - /* open dev-zero for our mmaping */ - mp.mp_fd = open("/dev/zero", O_RDWR, 0); - if (mp.mp_fd < 0) { - SET_POINTER(error_p, MPOOL_ERROR_OPEN_ZERO); - return NULL; - } - mp.mp_addr = start_addr; - /* we start at the front of the file */ - mp.mp_top = 0; - } - - /* - * Find out how many pages we need for our mpool structure. - * - * NOTE: this adds possibly unneeded space for mpool_block_t which - * may not be in this block. - */ - page_n = PAGES_IN_SIZE(&mp, sizeof(mpool_t)); - - /* now allocate us space for the actual struct */ - mp_p = alloc_pages(&mp, page_n, error_p); - if (mp_p == NULL) { - if (mp.mp_fd >= 0) { - (void)close(mp.mp_fd); - mp.mp_fd = -1; - } - return NULL; - } - - /* - * NOTE: we do not normally free the rest of the block here because - * we want to lesson the chance of an allocation overwriting the - * main structure. - */ - if (BIT_IS_SET(flags, MPOOL_FLAG_HEAVY_PACKING)) { - - /* we add a block header to the front of the block */ - block_p = (mpool_block_t *)mp_p; - - /* init the block header */ - block_p->mb_magic = BLOCK_MAGIC; - block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(&mp, page_n); - block_p->mb_next_p = NULL; - block_p->mb_magic2 = BLOCK_MAGIC; - - /* the mpool pointer is then the 2nd thing in the block */ - mp_p = FIRST_ADDR_IN_BLOCK(block_p); - free_addr = (char *)mp_p + sizeof(mpool_t); - - /* free the rest of the block */ - ret = free_pointer(&mp, free_addr, - (char *)block_p->mb_bounds_p - (char *)free_addr); - if (ret != MPOOL_ERROR_NONE) { - if (mp.mp_fd >= 0) { - (void)close(mp.mp_fd); - mp.mp_fd = -1; - } - /* NOTE: after this line mp_p will be invalid */ - (void)free_pages(block_p, SIZE_OF_PAGES(&mp, page_n), - BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)); - SET_POINTER(error_p, ret); - return NULL; - } - - /* - * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool - * header is not on the block linked list. - */ - - /* now copy our tmp structure into our new memory area */ - memcpy(mp_p, &mp, sizeof(mpool_t)); - - /* we setup min/max to our current address which is as good as any */ - mp_p->mp_min_p = block_p; - mp_p->mp_bounds_p = block_p->mb_bounds_p; - } - else { - /* now copy our tmp structure into our new memory area */ - memcpy(mp_p, &mp, sizeof(mpool_t)); - - /* we setup min/max to our current address which is as good as any */ - mp_p->mp_min_p = mp_p; - mp_p->mp_bounds_p = (char *)mp_p + SIZE_OF_PAGES(mp_p, page_n); - } - - SET_POINTER(error_p, MPOOL_ERROR_NONE); - return mp_p; -} - -/* - * int mpool_close - * - * DESCRIPTION: - * - * Close/free a memory allocation pool previously opened with - * mpool_open. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to our memory pool. - */ -int mpool_close(mpool_t *mp_p) -{ - mpool_block_t *block_p, *next_p; - void *addr; - unsigned long size; - int ret, final = MPOOL_ERROR_NONE; - - /* special case, just return no-error */ - if (mp_p == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLOSE, 0, 0, NULL, NULL, 0); - } - - /* - * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool - * header is not on the linked list. - */ - - /* free/invalidate the blocks */ - for (block_p = mp_p->mp_first_p; block_p != NULL; block_p = next_p) { - if (block_p->mb_magic != BLOCK_MAGIC - || block_p->mb_magic2 != BLOCK_MAGIC) { - final = MPOOL_ERROR_POOL_OVER; - break; - } - block_p->mb_magic = 0; - block_p->mb_magic2 = 0; - /* record the next pointer because it might be invalidated below */ - next_p = block_p->mb_next_p; - ret = free_pages(block_p, (char *)block_p->mb_bounds_p - (char *)block_p, - BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)); - if (ret != MPOOL_ERROR_NONE) { - final = ret; - } - } - - /* close /dev/zero if necessary */ - if (mp_p->mp_fd >= 0) { - (void)close(mp_p->mp_fd); - mp_p->mp_fd = -1; - } - - /* invalidate the mpool before we ditch it */ - mp_p->mp_magic = 0; - mp_p->mp_magic2 = 0; - - /* last we munmap the mpool pointer itself */ - if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) { - - /* if we are heavy packing then we need to free the 1st block later */ - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) { - addr = (char *)mp_p - sizeof(mpool_block_t); - } - else { - addr = mp_p; - } - size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, sizeof(mpool_t))); - - (void)munmap((caddr_t)addr, size); - } - - return final; -} - -/* - * int mpool_clear - * - * DESCRIPTION: - * - * Wipe an opened memory pool clean so we can start again. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to our memory pool. - */ -int mpool_clear(mpool_t *mp_p) -{ - mpool_block_t *block_p; - int final = MPOOL_ERROR_NONE, bit_n, ret; - void *first_p; - - /* special case, just return no-error */ - if (mp_p == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLEAR, 0, 0, NULL, NULL, 0); - } - - /* reset all of our free lists */ - for (bit_n = 0; bit_n <= MAX_BITS; bit_n++) { - mp_p->mp_free[bit_n] = NULL; - } - - /* free the blocks */ - for (block_p = mp_p->mp_first_p; - block_p != NULL; - block_p = block_p->mb_next_p) { - if (block_p->mb_magic != BLOCK_MAGIC - || block_p->mb_magic2 != BLOCK_MAGIC) { - final = MPOOL_ERROR_POOL_OVER; - break; - } - - first_p = FIRST_ADDR_IN_BLOCK(block_p); - - /* free the memory */ - ret = free_pointer(mp_p, first_p, MEMORY_IN_BLOCK(block_p)); - if (ret != MPOOL_ERROR_NONE) { - final = ret; - } - } - - return final; -} - -/* - * void *mpool_alloc - * - * DESCRIPTION: - * - * Allocate space for bytes inside of an already open memory pool. - * - * RETURNS: - * - * Success - Pointer to the address to use. - * - * Failure - NULL - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool - * - * byte_size -> Number of bytes to allocate in the pool. Must be >0. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, - int *error_p) -{ - struct FRAG *frag; - - if (!mp_p || mp_p->mp_magic != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_PNT); - return NULL; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); - return NULL; - } - - if (byte_size == 0) { - SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); - return NULL; - } - - frag = (struct FRAG *)alloc_mem(mp_p, byte_size + FRAG_OVERHEAD, error_p); - - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_ALLOC, byte_size, 0, (void *)frag, NULL, 0); - } - - frag->frag_size = byte_size; - return &frag->frag_ptr; -} - -/* - * void *mpool_calloc - * - * DESCRIPTION: - * - * Allocate space for elements of bytes in the memory pool and zero - * the space afterwards. - * - * RETURNS: - * - * Success - Pointer to the address to use. - * - * Failure - NULL - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. - * - * ele_n -> Number of elements to allocate. - * - * ele_size -> Number of bytes per element being allocated. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, - const unsigned long ele_size, int *error_p) -{ - struct FRAG *frag; - unsigned long byte_size; - - if (!mp_p || mp_p->mp_magic != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_PNT); - return NULL; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); - return NULL; - } - - if (ele_n == 0 || ele_size == 0) { - SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); - return NULL; - } - - byte_size = ele_n * ele_size; - - frag = alloc_mem(mp_p, byte_size + FRAG_OVERHEAD, error_p); - if (frag != NULL) { - memset(&frag->frag_ptr, 0, byte_size); - } - - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_CALLOC, ele_size, ele_n, (void *)frag, NULL, 0); - } - - frag->frag_size = byte_size; - return &frag->frag_ptr; -} - -/* - * int mpool_free - * - * DESCRIPTION: - * - * Free an address from a memory pool. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. - * - * addr <-> Address to free. - * - * size -> Size of the address being freed. - */ -int mpool_free(mpool_t *mp_p, void *addr) -{ - struct FRAG *frag = (struct FRAG *) (addr - FRAG_OVERHEAD); - - if (!mp_p || mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_FREE, 0, 0, NULL, addr, 0); - } - - if (addr == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - - return free_mem(mp_p, (void *)frag, frag->frag_size + FRAG_OVERHEAD); -} - -/* - * void *mpool_resize - * - * DESCRIPTION: - * - * Reallocate an address in a mmeory pool to a new size. This is - * different from realloc in that it needs the old address' size. If - * you don't have it then you need to allocate new space, copy the - * data, and free the old pointer yourself. - * - * RETURNS: - * - * Success - Pointer to the address to use. - * - * Failure - NULL - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. - * - * old_addr -> Previously allocated address. - * - * old_byte_size -> Size of the old address. Must be known, cannot be - * 0. - * - * new_byte_size -> New size of the allocation. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -void *mpool_resize(mpool_t *mp_p, void *old_addr, - const unsigned long new_byte_size, - int *error_p) -{ - unsigned long copy_size, new_size, old_size, fence; - struct FRAG *new_frag; - mpool_block_t *block_p; - int ret; - struct FRAG *old_frag = (struct FRAG *)(old_addr - FRAG_OVERHEAD); - unsigned long old_byte_size; - - if (old_addr == NULL) { - /* behave like realloc */ - return mpool_alloc(mp_p, new_byte_size, error_p); - } - - if (!mp_p || mp_p->mp_magic != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_PNT); - return NULL; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); - return NULL; - } - - old_byte_size = old_frag->frag_size; - if (old_byte_size == 0) { - SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); - return NULL; - } - - /* - * If the size is larger than a block then the allocation must be at - * the front of the block. - */ - if (old_byte_size + FRAG_OVERHEAD > MAX_BLOCK_USER_MEMORY(mp_p)) { - block_p = (mpool_block_t *)((char *)old_frag - sizeof(mpool_block_t)); - if (block_p->mb_magic != BLOCK_MAGIC - || block_p->mb_magic2 != BLOCK_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); - return NULL; - } - } - - /* make sure we have enough bytes */ - if (old_byte_size + FRAG_OVERHEAD < MIN_ALLOCATION) { - old_size = MIN_ALLOCATION; - } - else { - old_size = old_byte_size + FRAG_OVERHEAD; - } - - /* verify that the size matches exactly if we can */ - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { - fence = 0; - } - else if (old_size > 0) { - ret = check_magic((void *)old_frag, old_size); - if (ret != MPOOL_ERROR_NONE) { - SET_POINTER(error_p, ret); - return NULL; - } - fence = FENCE_SIZE; - } - - /* make sure we have enough bytes */ - if (new_byte_size < MIN_ALLOCATION) { - new_size = MIN_ALLOCATION; - } - else { - new_size = new_byte_size; - } - - /* - * NOTE: we could here see if the size is the same or less and then - * use the current memory and free the space above. This is harder - * than it sounds if we are changing the block size of the - * allocation. - */ - - /* we need to get another address */ - new_frag = alloc_mem(mp_p, new_byte_size + FRAG_OVERHEAD, error_p); - if (new_frag == NULL) { - /* error_p set in mpool_alloc */ - return NULL; - } - - if (new_byte_size > old_byte_size) { - copy_size = old_byte_size; - } - else { - copy_size = new_byte_size; - } - new_frag->frag_size = new_byte_size; - memcpy(&new_frag->frag_ptr, old_addr, copy_size); - - /* free the old address */ - ret = free_mem(mp_p, (void *)old_frag, old_byte_size + FRAG_OVERHEAD); - if (ret != MPOOL_ERROR_NONE) { - /* if the old free failed, try and free the new address */ - (void)free_mem(mp_p, (void *)new_frag, new_byte_size + FRAG_OVERHEAD); - SET_POINTER(error_p, ret); - return NULL; - } - - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_RESIZE, new_byte_size, - 0, (void *)new_frag, old_addr, old_byte_size); - } - - SET_POINTER(error_p, MPOOL_ERROR_NONE); - return &new_frag->frag_ptr; -} - - -void *mpool_resize2(mpool_t *mp_p, void *old_addr, - const unsigned long new_byte_size, - int *error_p) -{ - void *alloc = mpool_resize(mp_p, old_addr, new_byte_size, error_p); - if(!alloc && old_addr) - mpool_free(mp_p, old_addr); - return alloc; -} - -/* - * int mpool_stats - * - * DESCRIPTION: - * - * Return stats from the memory pool. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p -> Pointer to the memory pool. - * - * page_size_p <- Pointer to an unsigned integer which, if not NULL, - * will be set to the page-size of the pool. - * - * num_alloced_p <- Pointer to an unsigned long which, if not NULL, - * will be set to the number of pointers currently allocated in pool. - * - * user_alloced_p <- Pointer to an unsigned long which, if not NULL, - * will be set to the number of user bytes allocated in this pool. - * - * max_alloced_p <- Pointer to an unsigned long which, if not NULL, - * will be set to the maximum number of user bytes that have been - * allocated in this pool. - * - * tot_alloced_p <- Pointer to an unsigned long which, if not NULL, - * will be set to the total amount of space (including administrative - * overhead) used by the pool. - */ -int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, - unsigned long *num_alloced_p, - unsigned long *user_alloced_p, - unsigned long *max_alloced_p, - unsigned long *tot_alloced_p) -{ - if (mp_p == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - - SET_POINTER(page_size_p, mp_p->mp_page_size); - SET_POINTER(num_alloced_p, mp_p->mp_alloc_c); - SET_POINTER(user_alloced_p, mp_p->mp_user_alloc); - SET_POINTER(max_alloced_p, mp_p->mp_max_alloc); - SET_POINTER(tot_alloced_p, SIZE_OF_PAGES(mp_p, mp_p->mp_page_c)); - - return MPOOL_ERROR_NONE; -} - -/* - * int mpool_set_log_func - * - * DESCRIPTION: - * - * Set a logging callback function to be called whenever there was a - * memory transaction. See mpool_log_func_t. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. - * - * log_func -> Log function (defined in mpool.h) which will be called - * with each mpool transaction. - */ -int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func) -{ - if (mp_p == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - - mp_p->mp_log_func = log_func; - - return MPOOL_ERROR_NONE; -} - -/* - * int mpool_set_max_pages - * - * DESCRIPTION: - * - * Set the maximum number of pages that the library will use. Once it - * hits the limit it will return MPOOL_ERROR_NO_PAGES. - * - * NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages - * value will include the page with the mpool header structure in it. - * If the flag is _not_ set then the max-pages will not include this - * first page. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. - * - * max_pages -> Maximum number of pages used by the library. - */ -int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages) -{ - if (mp_p == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) { - mp_p->mp_max_pages = max_pages; - } - else { - /* - * If we are not heavy-packing the pool then we don't count the - * 1st page allocated which holds the mpool header structure. - */ - mp_p->mp_max_pages = max_pages + 1; - } - - return MPOOL_ERROR_NONE; -} - -/* - * const char *mpool_strerror - * - * DESCRIPTION: - * - * Return the corresponding string for the error number. - * - * RETURNS: - * - * Success - String equivalient of the error. - * - * Failure - String "invalid error code" - * - * ARGUMENTS: - * - * error -> Error number that we are converting. - */ -const char *mpool_strerror(const int error) -{ - switch (error) { - case MPOOL_ERROR_NONE: - return "no error"; - break; - case MPOOL_ERROR_ARG_NULL: - return "function argument is null"; - break; - case MPOOL_ERROR_ARG_INVALID: - return "function argument is invalid"; - break; - case MPOOL_ERROR_PNT: - return "invalid mpool pointer"; - break; - case MPOOL_ERROR_POOL_OVER: - return "mpool structure was overwritten"; - break; - case MPOOL_ERROR_PAGE_SIZE: - return "could not get system page-size"; - break; - case MPOOL_ERROR_OPEN_ZERO: - return "could not open /dev/zero"; - break; - case MPOOL_ERROR_NO_MEM: - return "no memory available"; - break; - case MPOOL_ERROR_MMAP: - return "problems with mmap"; - break; - case MPOOL_ERROR_SIZE: - return "error processing requested size"; - break; - case MPOOL_ERROR_TOO_BIG: - return "allocation exceeds pool max size"; - break; - case MPOOL_ERROR_MEM: - return "invalid memory address"; - break; - case MPOOL_ERROR_MEM_OVER: - return "memory lower bounds overwritten"; - break; - case MPOOL_ERROR_NOT_FOUND: - return "memory block not found in pool"; - break; - case MPOOL_ERROR_IS_FREE: - return "memory address has already been freed"; - break; - case MPOOL_ERROR_BLOCK_STAT: - return "invalid internal block status"; - break; - case MPOOL_ERROR_FREE_ADDR: - return "invalid internal free address"; - break; - case MPOOL_ERROR_SBRK_CONTIG: - return "sbrk did not return contiguous memory"; - break; - case MPOOL_ERROR_NO_PAGES: - return "no available pages left in pool"; - break; - case MPOOL_ERROR_ALLOC: - return "system alloc function failed"; - break; - case MPOOL_ERROR_PNT_OVER: - return "user pointer admin space overwritten"; - break; - default: - break; - } - - return "invalid error code"; -} diff --git a/libclamav/mpool-2.1.0/mpool.h b/libclamav/mpool-2.1.0/mpool.h deleted file mode 100644 index 7368a223f..000000000 --- a/libclamav/mpool-2.1.0/mpool.h +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Memory pool defines. - * - * Copyright 1996 by Gray Watson. - * - * This file is part of the mpool package. - * - * Permission to use, copy, modify, and distribute this software for - * any purpose and without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies, and that the name of Gray Watson not be used in advertising - * or publicity pertaining to distribution of the document or software - * without specific, written prior permission. - * - * Gray Watson makes no representations about the suitability of the - * software described herein for any purpose. It is provided "as is" - * without express or implied warranty. - * - * The author may be reached via http://256.com/gray/ - * - * $Id: mpool.h,v 1.4 2006/05/31 20:26:11 gray Exp $ - */ - -#ifndef __MPOOL_H__ -#define __MPOOL_H__ - -#include - -/* - * mpool flags to mpool_alloc or mpool_set_attr - */ - -/* - * Choose a best fit algorithm not first fit. This takes more CPU - * time but will result in a tighter heap. - */ -#define MPOOL_FLAG_BEST_FIT (1<<0) - -/* - * By default the library adds 2 bytes onto all allocations to insert - * a magic number that it can look for to determine how large a freed - * memory chunk is. This flag indicates that few if any frees are - * going to be performed on the pool and to not waste memory on these - * bytes. - */ -#define MPOOL_FLAG_NO_FREE (1<<1) - -/* - * This enables very heavy packing at the possible expense of CPU. - * This affects a number of parts of the library. - * - * By default the 1st page of memory is reserved for the main mpool - * structure. This flag will cause the rest of the 1st block to be - * available for use as user memory. - * - * By default the library looks through the memory when freed looking - * for a magic value. There is an internal max size that it will look - * and then it will give up. This flag forces it to look until it - * finds it. - */ -#define MPOOL_FLAG_HEAVY_PACKING (1<<2) - -/* - * Use sbrk not mmap to allocate pages. This is not recommended for - * normal use. - */ -#define MPOOL_FLAG_USE_SBRK (1<<3) - -/* - * Mpool error codes - */ -#define MPOOL_ERROR_NONE 1 /* no error */ -#define MPOOL_ERROR_ARG_NULL 2 /* function argument is null */ -#define MPOOL_ERROR_ARG_INVALID 3 /* function argument is invalid */ -#define MPOOL_ERROR_PNT 4 /* invalid mpool pointer */ -#define MPOOL_ERROR_POOL_OVER 5 /* mpool structure was overwritten */ -#define MPOOL_ERROR_PAGE_SIZE 6 /* could not get system page-size */ -#define MPOOL_ERROR_OPEN_ZERO 7 /* could not open /dev/zero */ -#define MPOOL_ERROR_NO_MEM 8 /* no memory available */ -#define MPOOL_ERROR_MMAP 9 /* problems with mmap */ -#define MPOOL_ERROR_SIZE 10 /* error processing requested size */ -#define MPOOL_ERROR_TOO_BIG 11 /* allocation exceeded max size */ -#define MPOOL_ERROR_MEM 12 /* invalid memory address */ -#define MPOOL_ERROR_MEM_OVER 13 /* memory lower bounds overwritten */ -#define MPOOL_ERROR_NOT_FOUND 14 /* memory block not found in pool */ -#define MPOOL_ERROR_IS_FREE 15 /* memory block already free */ -#define MPOOL_ERROR_BLOCK_STAT 16 /* invalid internal block status */ -#define MPOOL_ERROR_FREE_ADDR 17 /* invalid internal free address */ -#define MPOOL_ERROR_SBRK_CONTIG 18 /* sbrk did not return contiguous mem*/ -#define MPOOL_ERROR_NO_PAGES 19 /* ran out of pages in pool */ -#define MPOOL_ERROR_ALLOC 20 /* calloc,malloc,free,realloc failed */ -#define MPOOL_ERROR_PNT_OVER 21 /* pointer structure was overwritten */ - -/* - * Mpool function IDs for the mpool_log_func callback function. - */ -#define MPOOL_FUNC_CLOSE 1 /* mpool_close function called */ -#define MPOOL_FUNC_CLEAR 2 /* mpool_clear function called */ -#define MPOOL_FUNC_ALLOC 3 /* mpool_alloc function called */ -#define MPOOL_FUNC_CALLOC 4 /* mpool_calloc function called */ -#define MPOOL_FUNC_FREE 5 /* mpool_free function called */ -#define MPOOL_FUNC_RESIZE 6 /* mpool_resize function called */ - -/* - * void mpool_log_func_t - * - * DESCRIPTION: - * - * Mpool transaction log function. - * - * RETURNS: - * - * None. - * - * ARGUMENT: - * - * mp_p -> Associated mpool address. - * - * func_id -> Integer function ID which identifies which mpool - * function is being called. - * - * byte_size -> Optionally specified byte size. - * - * ele_n -> Optionally specified element number. For mpool_calloc - * only. - * - * new_addr -> Optionally specified new address. For mpool_alloc, - * mpool_calloc, and mpool_resize only. - * - * old_addr -> Optionally specified old address. For mpool_resize and - * mpool_free only. - * - * old_byte_size -> Optionally specified old byte size. For - * mpool_resize only. - */ -typedef void (*mpool_log_func_t)(const void *mp_p, - const int func_id, - const unsigned long byte_size, - const unsigned long ele_n, - const void *old_addr, const void *new_addr, - const unsigned long old_byte_size); - -#ifdef MPOOL_MAIN - -#include "mpool_loc.h" - -#else - -/* generic mpool type */ -typedef void mpool_t; - -#endif - -/*<<<<<<<<<< The below prototypes are auto-generated by fillproto */ - -/* - * mpool_t *mpool_open - * - * DESCRIPTION: - * - * Open/allocate a new memory pool. - * - * RETURNS: - * - * Success - Pool pointer which must be passed to mpool_close to - * deallocate. - * - * Failure - NULL - * - * ARGUMENTS: - * - * flags -> Flags to set attributes of the memory pool. See the top - * of mpool.h. - * - * page_size -> Set the internal memory page-size. This must be a - * multiple of the getpagesize() value. Set to 0 for the default. - * - * start_addr -> Starting address to try and allocate memory pools. - * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -extern -mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, - void *start_addr, int *error_p); - -/* - * int mpool_close - * - * DESCRIPTION: - * - * Close/free a memory allocation pool previously opened with - * mpool_open. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to our memory pool. - */ -extern -int mpool_close(mpool_t *mp_p); - -/* - * int mpool_clear - * - * DESCRIPTION: - * - * Wipe an opened memory pool clean so we can start again. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to our memory pool. - */ -extern -int mpool_clear(mpool_t *mp_p); - -/* - * void *mpool_alloc - * - * DESCRIPTION: - * - * Allocate space for bytes inside of an already open memory pool. - * - * RETURNS: - * - * Success - Pointer to the address to use. - * - * Failure - NULL - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. If NULL then it will do a - * normal malloc. - * - * byte_size -> Number of bytes to allocate in the pool. Must be >0. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -extern -void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, - int *error_p); - -/* - * void *mpool_calloc - * - * DESCRIPTION: - * - * Allocate space for elements of bytes in the memory pool and zero - * the space afterwards. - * - * RETURNS: - * - * Success - Pointer to the address to use. - * - * Failure - NULL - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. If NULL then it will do a - * normal calloc. - * - * ele_n -> Number of elements to allocate. - * - * ele_size -> Number of bytes per element being allocated. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -extern -void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, - const unsigned long ele_size, int *error_p); - -/* - * int mpool_free - * - * DESCRIPTION: - * - * Free an address from a memory pool. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. If NULL then it will do a - * normal free. - * - * addr <-> Address to free. - * - * size -> Size of the address being freed. - */ -extern -int mpool_free(mpool_t *mp_p, void *addr); - -/* - * void *mpool_resize - * - * DESCRIPTION: - * - * Reallocate an address in a mmeory pool to a new size. This is - * different from realloc in that it needs the old address' size. If - * you don't have it then you need to allocate new space, copy the - * data, and free the old pointer yourself. - * - * RETURNS: - * - * Success - Pointer to the address to use. - * - * Failure - NULL - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. If NULL then it will do a - * normal realloc. - * - * old_addr -> Previously allocated address. - * - * old_byte_size -> Size of the old address. Must be known, cannot be - * 0. - * - * new_byte_size -> New size of the allocation. - * - * error_p <- Pointer to integer which, if not NULL, will be set with - * a mpool error code. - */ -extern -void *mpool_resize(mpool_t *mp_p, void *old_addr, - const unsigned long new_byte_size, - int *error_p); -extern -void *mpool_resize2(mpool_t *mp_p, void *old_addr, - const unsigned long new_byte_size, - int *error_p); - -/* - * int mpool_stats - * - * DESCRIPTION: - * - * Return stats from the memory pool. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p -> Pointer to the memory pool. - * - * page_size_p <- Pointer to an unsigned integer which, if not NULL, - * will be set to the page-size of the pool. - * - * num_alloced_p <- Pointer to an unsigned long which, if not NULL, - * will be set to the number of pointers currently allocated in pool. - * - * user_alloced_p <- Pointer to an unsigned long which, if not NULL, - * will be set to the number of user bytes allocated in this pool. - * - * max_alloced_p <- Pointer to an unsigned long which, if not NULL, - * will be set to the maximum number of user bytes that have been - * allocated in this pool. - * - * tot_alloced_p <- Pointer to an unsigned long which, if not NULL, - * will be set to the total amount of space (including administrative - * overhead) used by the pool. - */ -extern -int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, - unsigned long *num_alloced_p, - unsigned long *user_alloced_p, - unsigned long *max_alloced_p, - unsigned long *tot_alloced_p); - -/* - * int mpool_set_log_func - * - * DESCRIPTION: - * - * Set a logging callback function to be called whenever there was a - * memory transaction. See mpool_log_func_t. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. - * - * log_func -> Log function (defined in mpool.h) which will be called - * with each mpool transaction. - */ -extern -int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func); - -/* - * int mpool_set_max_pages - * - * DESCRIPTION: - * - * Set the maximum number of pages that the library will use. Once it - * hits the limit it will return MPOOL_ERROR_NO_PAGES. - * - * NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages - * value will include the page with the mpool header structure in it. - * If the flag is _not_ set then the max-pages will not include this - * first page. - * - * RETURNS: - * - * Success - MPOOL_ERROR_NONE - * - * Failure - Mpool error code - * - * ARGUMENTS: - * - * mp_p <-> Pointer to the memory pool. - * - * max_pages -> Maximum number of pages used by the library. - */ -extern -int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages); - -/* - * const char *mpool_strerror - * - * DESCRIPTION: - * - * Return the corresponding string for the error number. - * - * RETURNS: - * - * Success - String equivalient of the error. - * - * Failure - String "invalid error code" - * - * ARGUMENTS: - * - * error -> Error number that we are converting. - */ -extern -const char *mpool_strerror(const int error); - -/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ - -#endif /* ! __MPOOL_H__ */ diff --git a/libclamav/mpool-2.1.0/mpool_loc.h b/libclamav/mpool-2.1.0/mpool_loc.h deleted file mode 100644 index 3d33f5d92..000000000 --- a/libclamav/mpool-2.1.0/mpool_loc.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Memory pool local defines. - * - * Copyright 1996 by Gray Watson. - * - * This file is part of the mpool package. - * - * Permission to use, copy, modify, and distribute this software for - * any purpose and without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies, and that the name of Gray Watson not be used in advertising - * or publicity pertaining to distribution of the document or software - * without specific, written prior permission. - * - * Gray Watson makes no representations about the suitability of the - * software described herein for any purpose. It is provided "as is" - * without express or implied warranty. - * - * The author may be reached via http://256.com/gray/ - * - * $Id: mpool_loc.h,v 1.2 2005/05/20 20:08:54 gray Exp $ - */ - -#ifndef __MPOOL_LOC_H__ -#define __MPOOL_LOC_H__ - -#define MPOOL_MAGIC 0xABACABA /* magic for struct */ -#define BLOCK_MAGIC 0xB1B1007 /* magic for blocks */ -#define FENCE_MAGIC0 (unsigned char)(0xFAU) /* 1st magic mem byte */ -#define FENCE_MAGIC1 (unsigned char)(0xD3U) /* 2nd magic mem byte */ - -#define FENCE_SIZE 2 /* fence space */ -#define MIN_ALLOCATION (sizeof(mpool_free_t)) /* min alloc */ -#define MAX_FREE_SEARCH 10240 /* max size to search */ -#define MAX_FREE_LIST_SEARCH 100 /* max looking for free mem */ - -/* - * bitflag tools for Variable and a Flag - */ -#define BIT_FLAG(x) (1 << (x)) -#define BIT_SET(v,f) (v) |= (f) -#define BIT_CLEAR(v,f) (v) &= ~(f) -#define BIT_IS_SET(v,f) ((v) & (f)) -#define BIT_TOGGLE(v,f) (v) ^= (f) - -#define SET_POINTER(pnt, val) \ - do { \ - if ((pnt) != NULL) { \ - (*(pnt)) = (val); \ - } \ - } while(0) - -#define BLOCK_FLAG_USED BIT_FLAG(0) /* block is used */ -#define BLOCK_FLAG_FREE BIT_FLAG(1) /* block is free */ - -#define DEFAULT_PAGE_MULT 16 /* pagesize = this * getpagesize*/ - -/* How many pages SIZE bytes resides in. We add in the block header. */ -#define PAGES_IN_SIZE(mp_p, size) (((size) + sizeof(mpool_block_t) + \ - (mp_p)->mp_page_size - 1) / \ - (mp_p)->mp_page_size) -#define SIZE_OF_PAGES(mp_p, page_n) ((page_n) * (mp_p)->mp_page_size) -#define MAX_BITS 30 /* we only can allocate 1gb chunks */ - -#define MAX_BLOCK_USER_MEMORY(mp_p) ((mp_p)->mp_page_size - \ - sizeof(mpool_block_t)) -#define FIRST_ADDR_IN_BLOCK(block_p) (void *)((char *)(block_p) + \ - sizeof(mpool_block_t)) -#define MEMORY_IN_BLOCK(block_p) ((char *)(block_p)->mb_bounds_p - \ - ((char *)(block_p) + \ - sizeof(mpool_block_t))) - -typedef struct { - unsigned int mp_magic; /* magic number for struct */ - unsigned int mp_flags; /* flags for the struct */ - unsigned long mp_alloc_c; /* number of allocations */ - unsigned long mp_user_alloc; /* user bytes allocated */ - unsigned long mp_max_alloc; /* maximum user bytes allocated */ - unsigned int mp_page_c; /* number of pages allocated */ - unsigned int mp_max_pages; /* maximum number of pages to use */ - unsigned int mp_page_size; /* page-size of our system */ - int mp_fd; /* fd for /dev/zero if mmap-ing */ - off_t mp_top; /* top of our allocations in fd */ - mpool_log_func_t mp_log_func; /* log callback function */ - void *mp_addr; /* current address for mmaping */ - void *mp_min_p; /* min address in pool for checks */ - void *mp_bounds_p; /* max address in pool for checks */ - struct mpool_block_st *mp_first_p; /* first memory block we are using */ - struct mpool_block_st *mp_last_p; /* last memory block we are using */ - struct mpool_block_st *mp_free[MAX_BITS + 1]; /* free lists based on size */ - unsigned int mp_magic2; /* upper magic for overwrite sanity */ -} mpool_t; - -/* for debuggers to be able to interrogate the generic type in the .h file */ -typedef mpool_t mpool_ext_t; - -/* - * Block header structure. This structure *MUST* be long-word - * aligned. - */ -typedef struct mpool_block_st { - unsigned int mb_magic; /* magic number for block header */ - void *mb_bounds_p; /* block boundary location */ - struct mpool_block_st *mb_next_p; /* linked list next pointer */ - unsigned int mb_magic2; /* upper magic for overwrite sanity */ -} mpool_block_t; - -/* - * Free list structure. - */ -typedef struct { - void *mf_next_p; /* pointer to the next free address */ - unsigned long mf_size; /* size of the free block */ -} mpool_free_t; - -#endif /* ! __MPOOL_LOC_H__ */ diff --git a/libclamav/mpool-2.1.0/mpool_t.c b/libclamav/mpool-2.1.0/mpool_t.c deleted file mode 100644 index 37c25d218..000000000 --- a/libclamav/mpool-2.1.0/mpool_t.c +++ /dev/null @@ -1,914 +0,0 @@ -/* - * Memory pool test program. - * - * Copyright 1996 by Gray Watson. - * - * This file is part of the mpool package. - * - * Permission to use, copy, modify, and distribute this software for - * any purpose and without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies, and that the name of Gray Watson not be used in advertising - * or publicity pertaining to distribution of the document or software - * without specific, written prior permission. - * - * Gray Watson makes no representations about the suitability of the - * software described herein for any purpose. It is provided "as is" - * without express or implied warranty. - * - * The author may be reached via http://256.com/gray/ - * - * $Id: mpool_t.c,v 1.2 2005/05/20 20:08:55 gray Exp $ - */ - -/* - * Test program for the malloc library. Current it is interactive although - * should be script based. - */ - -#include -#include -#include -#include -#include -#include - -#include "mpool.h" - -#ifdef __GNUC__ -#ident "$Id: mpool_t.c,v 1.2 2005/05/20 20:08:55 gray Exp $" -#else -static char *rcs_id = "$Id: mpool_t.c,v 1.2 2005/05/20 20:08:55 gray Exp $"; -#endif - -#define DEFAULT_ITERATIONS 10000 -#define MAX_POINTERS 1024 -#define MAX_ALLOC (1024 * 1024) -#define MIN_AVAIL 10 - -#define RANDOM_VALUE(x) ((random() % ((x) * 10)) / 10) - -/* pointer tracking structure */ -struct pnt_info_st { - long pi_crc; /* crc of storage */ - long pi_size; /* size of storage */ - void *pi_pnt; /* pnt to storage */ - struct pnt_info_st *pi_next; /* pnt to next */ -}; - -typedef struct pnt_info_st pnt_info_t; - -static pnt_info_t *pointer_grid; - -/* argument variables */ -static int best_fit_b = 0; /* set best fit flag */ -static int heavy_pack_b = 0; /* set heavy pack flg*/ -static int interactive_b = 0; /* interactive flag */ -static int log_trxn_b = 0; /* log mem trxns */ -static long max_alloc = MAX_ALLOC; /* amt of mem to use */ -static int max_pages_n = 0; /* max # pages */ -static int use_malloc_b = 0; /* use system alloc */ -static int max_pointers = MAX_POINTERS; /* # of pnts to use */ -static int no_free_b = 0; /* set no free flag */ -static long page_size = 0; /* mpool pagesize */ -static int use_sbrk_b = 0; /* use sbrk not mmap */ -static unsigned int seed_random = 0; /* random seed */ -static int default_iter_n = DEFAULT_ITERATIONS; /* # of iters */ -static int verbose_b = 0; /* verbose flag */ - -/* - * static long hex_to_long - * - * DESCRIPTION: - * - * Hexadecimal string to integer translation. - * - * RETURNS: - * - * Long value of converted hex string. - * - * ARGUMENTS: - * - * str -> Hex string we are converting. - */ -static long hex_to_long(const char *str) -{ - long ret; - const char *str_p = str; - - /* strip off spaces */ - for (; *str_p == ' ' || *str_p == '\t'; str_p++) { - } - - /* skip a leading 0[xX] */ - if (*str_p == '0' && (*(str_p + 1) == 'x' || *(str_p + 1) == 'X')) { - str_p += 2; - } - - for (ret = 0;; str_p++) { - if (*str_p >= '0' && *str_p <= '9') { - ret = ret * 16 + (*str_p - '0'); - } - else if (*str_p >= 'a' && *str_p <= 'f') { - ret = ret * 16 + (*str_p - 'a' + 10); - } - else if (*str_p >= 'A' && *str_p <= 'F') { - ret = ret * 16 + (*str_p - 'A' + 10); - } - else { - break; - } - } - - return ret; -} - -/* - * static void* get_address - * - * DESCRIPTION: - * - * Read an address from the user. - * - * RETURNS: - * - * Address read in from user. - * - * ARGUMENTS: - * - * None. - */ -static void *get_address(void) -{ - char line[80]; - void *pnt; - - do { - (void)printf("Enter a hex address: "); - if (fgets(line, sizeof(line), stdin) == NULL) { - return NULL; - } - } while (line[0] == '\0'); - - pnt = (void *)hex_to_long(line); - - return pnt; -} - -/* - * static void do_random - * - * DESCRIPTION: - * - * Try ITER_N random program iterations, returns 1 on success else 0 - * - * RETURNS: - * - * None. - * - * ARGUMENTS: - * - * pool <-> Out memory pool. - * - * iter_n -> Number of iterations to run. - */ -static void do_random(mpool_t *pool, const int iter_n) -{ - int iter_c, free_c, ret; - long max = max_alloc, amount; - char *chunk_p; - void *new_pnt; - pnt_info_t *free_p, *used_p = NULL; - pnt_info_t *pnt_p, *last_p; - - if (use_malloc_b) { - pointer_grid = (pnt_info_t *)malloc(sizeof(pnt_info_t) * max_pointers); - } - else { - pointer_grid = (pnt_info_t *)mpool_alloc(pool, - sizeof(pnt_info_t) * max_pointers, - &ret); - } - if (pointer_grid == NULL) { - (void)printf("mpool_t: problems allocating %d pointer slots: %s\n", - max_pointers, strerror(errno)); - return; - } - - /* initialize free list */ - free_p = pointer_grid; - for (pnt_p = pointer_grid; pnt_p < pointer_grid + max_pointers; pnt_p++) { - pnt_p->pi_size = 0; - pnt_p->pi_pnt = NULL; - pnt_p->pi_next = pnt_p + 1; - } - /* redo the last next pointer */ - (pnt_p - 1)->pi_next = NULL; - free_c = max_pointers; - - for (iter_c = 0; iter_c < iter_n;) { - int which; - - /* special case when doing non-linear stuff, sbrk took all memory */ - if (max < MIN_AVAIL && free_c == max_pointers) { - break; - } - - if (free_c < max_pointers && used_p == NULL) { - (void)fprintf(stderr, "mpool_t: problem with test program free list\n"); - exit(1); - } - - /* decide whether to malloc a new pointer or free/realloc an existing */ - which = RANDOM_VALUE(4); - - /* - * < MIN_AVAIL means alloc as long as we have enough memory and - * there are free slots we do an allocation, else we free - */ - if (free_c == max_pointers - || (free_c > 0 && which < 3 && max >= MIN_AVAIL)) { - - while (1) { - amount = RANDOM_VALUE(max / 2); - if (amount > 0) { - break; - } - } - which = RANDOM_VALUE(9); - pnt_p = NULL; - - switch (which) { - - case 0: case 1: case 2: - pnt_p = free_p; - if (use_malloc_b) { - pnt_p->pi_pnt = malloc(amount); - } - else { - pnt_p->pi_pnt = mpool_alloc(pool, amount, &ret); - } - - if (verbose_b) { - (void)printf("%d: malloc %ld (max %ld) into slot %d. got %#lx\n", - iter_c + 1, amount, max, pnt_p - pointer_grid, - (long)pnt_p->pi_pnt); - } - - if (pnt_p->pi_pnt == NULL) { - (void)printf("malloc of %ld failed: %s\n", - amount, - (use_malloc_b ? strerror(errno) : mpool_strerror(ret))); - } - pnt_p->pi_size = amount; - break; - - case 3: case 4: case 5: - pnt_p = free_p; - if (use_malloc_b) { - pnt_p->pi_pnt = calloc(amount, sizeof(char)); - } - else { - pnt_p->pi_pnt = mpool_calloc(pool, amount, sizeof(char), &ret); - } - - if (verbose_b) { - (void)printf("%d: calloc %ld (max %ld) into slot %d. got %#lx\n", - iter_c + 1, amount, max, pnt_p - pointer_grid, - (long)pnt_p->pi_pnt); - } - - /* test the returned block to make sure that is has been cleared */ - if (pnt_p->pi_pnt == NULL) { - (void)printf("calloc of %ld failed: %s\n", - amount, - (use_malloc_b ? strerror(errno) : mpool_strerror(ret))); - } - else { - for (chunk_p = pnt_p->pi_pnt; - chunk_p < (char *)pnt_p->pi_pnt + amount; - chunk_p++) { - if (*chunk_p != '\0') { - (void)printf("calloc of %ld not zeroed on iteration #%d\n", - amount, iter_c + 1); - break; - } - } - pnt_p->pi_size = amount; - } - break; - - case 6: case 7: case 8: - if (free_c == max_pointers) { - continue; - } - - which = RANDOM_VALUE(max_pointers - free_c); - for (pnt_p = used_p; which > 0; which--) { - pnt_p = pnt_p->pi_next; - } - - if (use_malloc_b) { - new_pnt = realloc(pnt_p->pi_pnt, amount); - } - else { - new_pnt = mpool_resize(pool, pnt_p->pi_pnt, amount, - &ret); - } - - if (verbose_b) { - (void)printf("%d: resize %#lx from %ld to %ld (max %ld) slot %d. " - "got %#lx\n", - iter_c + 1, (long)pnt_p->pi_pnt, pnt_p->pi_size, amount, - max, pnt_p - pointer_grid, (long)new_pnt); - } - - if (new_pnt == NULL) { - (void)printf("resize of %#lx old size %ld new size %ld failed: %s\n", - (long)pnt_p->pi_pnt, pnt_p->pi_size, amount, - (use_malloc_b ? strerror(errno) : mpool_strerror(ret))); - pnt_p->pi_pnt = NULL; - pnt_p->pi_size = 0; - } - else { - /* we effectively freed the old memory */ - max += pnt_p->pi_size; - pnt_p->pi_pnt = new_pnt; - pnt_p->pi_size = amount; - } - break; - - default: - break; - } - - if (pnt_p != NULL && pnt_p->pi_pnt != NULL) { - if (pnt_p == free_p) { - free_p = pnt_p->pi_next; - pnt_p->pi_next = used_p; - used_p = pnt_p; - free_c--; - } - - max -= amount; - iter_c++; - } - continue; - } - - /* - * choose a rand slot to free and make sure it is not a free-slot - */ - which = RANDOM_VALUE(max_pointers - free_c); - /* find pnt in the used list */ - last_p = NULL; - for (pnt_p = used_p, last_p = NULL; - pnt_p != NULL && which > 0; - last_p = pnt_p, pnt_p = pnt_p->pi_next, which--) { - } - if (pnt_p == NULL) { - /* huh? error here */ - abort(); - } - if (last_p == NULL) { - used_p = pnt_p->pi_next; - } - else { - last_p->pi_next = pnt_p->pi_next; - } - - if (use_malloc_b) { - free(pnt_p->pi_pnt); - } - else { - ret = mpool_free(pool, pnt_p->pi_pnt); - if (ret != MPOOL_ERROR_NONE) { - (void)printf("free error on pointer '%#lx' of size %ld: %s\n", - (long)pnt_p->pi_pnt, pnt_p->pi_size, - mpool_strerror(ret)); - } - } - - if (verbose_b) { - (void)printf("%d: free'd %ld bytes from slot %d (%#lx)\n", - iter_c + 1, pnt_p->pi_size, pnt_p - pointer_grid, - (long)pnt_p->pi_pnt); - } - - pnt_p->pi_pnt = NULL; - pnt_p->pi_next = free_p; - free_p = pnt_p; - free_c++; - - max += pnt_p->pi_size; - iter_c++; - } - - /* free used pointers */ - for (pnt_p = pointer_grid; pnt_p < pointer_grid + max_pointers; pnt_p++) { - if (pnt_p->pi_pnt != NULL) { - if (use_malloc_b) { - free(pnt_p->pi_pnt); - } - else { - ret = mpool_free(pool, pnt_p->pi_pnt); - if (ret != MPOOL_ERROR_NONE) { - (void)printf("free error on pointer '%#lx' of size %ld: %s\n", - (long)pnt_p->pi_pnt, pnt_p->pi_size, - mpool_strerror(ret)); - } - } - } - } - - if (use_malloc_b) { - free(pointer_grid); - } - else { - ret = mpool_free(pool, pointer_grid); - if (ret != MPOOL_ERROR_NONE) { - (void)printf("free error on grid pointer: %s\n", mpool_strerror(ret)); - } - } -} - -/* - * static void do_interactive - * - * DESCRIPTION: - * - * Run the interactive section of the program. - * - * RETURNS: - * - * None. - * - * ARGUMENTS: - * - * pool <-> Out memory pool. - */ -static void do_interactive(mpool_t *pool) -{ - int len, ret; - char line[128], *line_p; - void *pnt, *new_pnt; - - (void)printf("Mpool test program. Type 'help' for assistance.\n"); - - for (;;) { - (void)printf("> "); - if (fgets(line, sizeof(line), stdin) == NULL) { - break; - } - line_p = strchr(line, '\n'); - if (line_p != NULL) { - *line_p = '\0'; - } - - len = strlen(line); - if (len == 0) { - continue; - } - - if (strncmp(line, "?", len) == 0 - || strncmp(line, "help", len) == 0) { - (void)printf("\thelp - print this message\n\n"); - - (void)printf("\tmalloc - allocate memory\n"); - (void)printf("\tcalloc - allocate/clear memory\n"); - (void)printf("\tresize - resize memory\n"); - (void)printf("\tfree - deallocate memory\n\n"); - - (void)printf("\tclear - clear the pool\n"); - (void)printf("\toverwrite - overwrite some memory to test errors\n"); - (void)printf("\trandom - randomly execute a number of [de] allocs\n"); - - (void)printf("\tquit - quit this test program\n"); - continue; - } - - if (strncmp(line, "quit", len) == 0) { - break; - } - - if (strncmp(line, "malloc", len) == 0) { - int size; - - (void)printf("How much to malloc: "); - if (fgets(line, sizeof(line), stdin) == NULL) { - break; - } - size = atoi(line); - pnt = mpool_alloc(pool, size, &ret); - if (pnt == NULL) { - (void)printf("malloc(%d) failed: %s\n", size, mpool_strerror(ret)); - } - else { - (void)printf("malloc(%d) returned '%#lx'\n", size, (long)pnt); - } - continue; - } - - if (strncmp(line, "calloc", len) == 0) { - int size; - - (void)printf("How much to calloc: "); - if (fgets(line, sizeof(line), stdin) == NULL) { - break; - } - size = atoi(line); - pnt = mpool_calloc(pool, size, sizeof(char), &ret); - if (pnt == NULL) { - (void)printf("calloc(%d) failed: %s\n", size, mpool_strerror(ret)); - } - else { - (void)printf("calloc(%d) returned '%#lx'\n", size, (long)pnt); - } - continue; - } - - if (strncmp(line, "resize", len) == 0) { - int size, old_size; - - pnt = get_address(); - - (void)printf("Old size of allocation: "); - if (fgets(line, sizeof(line), stdin) == NULL) { - break; - } - old_size = atoi(line); - (void)printf("New size of allocation: "); - if (fgets(line, sizeof(line), stdin) == NULL) { - break; - } - size = atoi(line); - - new_pnt = mpool_resize(pool, pnt, size, &ret); - if (new_pnt == NULL) { - (void)printf("resize(%#lx, %d) failed: %s\n", - (long)pnt, size, mpool_strerror(ret)); - } - else { - (void)printf("resize(%#lx, %d) returned '%#lx'\n", - (long)pnt, size, (long)new_pnt); - } - continue; - } - - if (strncmp(line, "free", len) == 0) { - int old_size; - - pnt = get_address(); - - (void)printf("Old minimum size we are freeing: "); - if (fgets(line, sizeof(line), stdin) == NULL) { - break; - } - old_size = atoi(line); - ret = mpool_free(pool, pnt); - if (ret != MPOOL_ERROR_NONE) { - (void)fprintf(stderr, "free failed: %s\n", mpool_strerror(ret)); - } - continue; - } - - if (strncmp(line, "clear", len) == 0) { - ret = mpool_clear(pool); - if (ret == MPOOL_ERROR_NONE) { - (void)fprintf(stderr, "clear succeeded\n"); - } - else { - (void)fprintf(stderr, "clear failed: %s\n", mpool_strerror(ret)); - } - continue; - } - - if (strncmp(line, "overwrite", len) == 0) { - char *overwrite = "OVERWRITTEN"; - - pnt = get_address(); - memcpy((char *)pnt, overwrite, strlen(overwrite)); - (void)printf("Done.\n"); - continue; - } - - /* do random heap hits */ - if (strncmp(line, "random", len) == 0) { - int iter_n; - - (void)printf("How many iterations[%d]: ", default_iter_n); - if (fgets(line, sizeof(line), stdin) == NULL) { - break; - } - if (line[0] == '\0' || line[0] == '\n') { - iter_n = default_iter_n; - } - else { - iter_n = atoi(line); - } - - do_random(pool, iter_n); - continue; - } - - (void)printf("Unknown command '%s'. Type 'help' for assistance.\n", line); - } -} - -/* - * static void log_func - * - * DESCRIPTION: - * - * Mpool transaction log function. - * - * RETURNS: - * - * None. - * - * ARGUMENT: - * - * mp_p -> Associated mpool address. - * - * func_id -> Integer function ID which identifies which mpool - * function is being called. - * - * byte_size -> Optionally specified byte size. - * - * ele_n -> Optionally specified element number. For mpool_calloc - * only. - * - * new_addr -> Optionally specified new address. For mpool_alloc, - * mpool_calloc, and mpool_resize only. - * - * old_addr -> Optionally specified old address. For mpool_resize and - * mpool_free only. - * - * old_byte_size -> Optionally specified old byte size. For - * mpool_resize only. - */ -static void log_func(const void *mp_p, const int func_id, - const unsigned long byte_size, - const unsigned long ele_n, - const void *new_addr, const void *old_addr, - const unsigned long old_byte_size) -{ - (void)printf("mp %#lx ", (long)mp_p); - - switch (func_id) { - - case MPOOL_FUNC_CLOSE: - (void)printf("close\n"); - break; - - case MPOOL_FUNC_CLEAR: - (void)printf("clear\n"); - break; - - case MPOOL_FUNC_ALLOC: - (void)printf("alloc %lu bytes got %#lx\n", - byte_size, (long)new_addr); - break; - - case MPOOL_FUNC_CALLOC: - (void)printf("calloc %lu ele size, %lu ele number, got %#lx\n", - byte_size, ele_n, (long)new_addr); - break; - - case MPOOL_FUNC_FREE: - (void)printf("free %#lx of %lu bytes\n", (long)old_addr, byte_size); - break; - - case MPOOL_FUNC_RESIZE: - (void)printf("resize %#lx of %lu bytes to %lu bytes, got %#lx\n", - (long)old_addr, old_byte_size, byte_size, - (long)new_addr); - break; - - default: - (void)printf("unknown function %d, %lu bytes\n", func_id, byte_size); - break; - } -} - -/* - * static void usage - * - * DESCRIPTION: - * - * Print a usage message. - * - * RETURNS: - * - * None. - * - * ARGUMENTS: - * - * None. - */ -static void usage(void) -{ - (void)fprintf(stderr, - "Usage: mpool_t [-bhHilMnsv] [-m size] [-p number] " - "[-P size] [-S seed] [-t times]\n"); - (void)fprintf(stderr, - " -b set MPOOL_FLAG_BEST_FIT\n" - " -h set MPOOL_FLAG_NO_FREE\n" - " -H use system heap not mpool\n" - " -i turn on interactive mode\n" - " -l log memory transactions\n" - " -M max number pages in mpool\n" - " -n set MPOOL_FLAG_NO_FREE\n" - " -s use sbrk instead of mmap\n" - " -v enable verbose messages\n" - " -m size maximum allocation to test\n" - " -p max-pnts number of pointers to test\n" - " -S seed-rand seed for random function\n" - " -t interations number of iterations to run\n"); - exit(1); -} - -/* - * static void process_args - * - * DESCRIPTION: - * - * Process our arguments. - * - * RETURNS: - * - * None. - * - * ARGUMENTS: - * - * None. - */ -static void process_args(int argc, char ** argv) -{ - argc--, argv++; - - /* process the args */ - for (; *argv != NULL; argv++, argc--) { - if (**argv != '-') { - continue; - } - - switch (*(*argv + 1)) { - - case 'b': - best_fit_b = 1; - break; - case 'h': - heavy_pack_b = 1; - break; - case 'H': - use_malloc_b = 1; - break; - case 'i': - interactive_b = 1; - break; - case 'l': - log_trxn_b = 1; - break; - case 'm': - argv++, argc--; - if (argc <= 0) { - usage(); - } - max_alloc = atoi(*argv); - break; - case 'M': - max_pages_n = 1; - break; - case 'n': - no_free_b = 1; - break; - case 'p': - argv++, argc--; - if (argc <= 0) { - usage(); - } - max_pointers = atoi(*argv); - break; - case 'P': - argv++, argc--; - if (argc <= 0) { - usage(); - } - page_size = atoi(*argv); - break; - case 'S': - argv++, argc--; - if (argc <= 0) { - usage(); - } - seed_random = atoi(*argv); - break; - case 't': - argv++, argc--; - if (argc <= 0) { - usage(); - } - default_iter_n = atoi(*argv); - break; - case 'v': - verbose_b = 1; - break; - default: - usage(); - break; - } - } -} - -/* - * Main routine - */ -int main(int argc, char **argv) -{ - int ret; - unsigned int flags = 0, pool_page_size; - unsigned long num_alloced, user_alloced, max_alloced, tot_alloced; - mpool_t *pool; - - process_args(argc, argv); - - /* repeat until we get a non 0 seed */ - while (seed_random == 0) { - seed_random = time(0) ^ getpid(); - } - (void)srandom(seed_random); - - (void)printf("Random seed is %u\n", seed_random); - - if (best_fit_b) { - flags |= MPOOL_FLAG_BEST_FIT; - } - if (heavy_pack_b) { - flags |= MPOOL_FLAG_HEAVY_PACKING; - } - if (no_free_b) { - flags |= MPOOL_FLAG_NO_FREE; - } - if (use_sbrk_b) { - flags |= MPOOL_FLAG_USE_SBRK; - } - - /* open our memory pool */ - pool = mpool_open(flags, page_size, NULL, &ret); - if (pool == NULL) { - (void)fprintf(stderr, "Error in mpool_open: %s\n", mpool_strerror(ret)); - exit(1); - } - - /* are we logging transactions */ - if (log_trxn_b) { - ret = mpool_set_log_func(pool, log_func); - if (ret != MPOOL_ERROR_NONE) { - (void)fprintf(stderr, "Error in mpool_set_log_func: %s\n", - mpool_strerror(ret)); - } - } - - if (max_pages_n > 0) { - ret = mpool_set_max_pages(pool, max_pages_n); - if (ret != MPOOL_ERROR_NONE) { - (void)fprintf(stderr, "Error in mpool_set_max_pages: %s\n", - mpool_strerror(ret)); - } - } - - if (interactive_b) { - do_interactive(pool); - } - else { - (void)printf("Running %d tests (use -i for interactive)...\n", - default_iter_n); - (void)fflush(stdout); - - do_random(pool, default_iter_n); - } - - /* get stats from the pool */ - ret = mpool_stats(pool, &pool_page_size, &num_alloced, &user_alloced, - &max_alloced, &tot_alloced); - if (ret == MPOOL_ERROR_NONE) { - (void)printf("Pool page size = %d. Number active allocated = %lu\n", - pool_page_size, num_alloced); - (void)printf("User bytes allocated = %lu. Max space allocated = %lu\n", - user_alloced, max_alloced); - (void)printf("Total space allocated = %lu\n", tot_alloced); - } - else { - (void)fprintf(stderr, "Error in mpool_stats: %s\n", mpool_strerror(ret)); - } - - /* close the pool */ - ret = mpool_close(pool); - if (ret != MPOOL_ERROR_NONE) { - (void)fprintf(stderr, "Error in mpool_close: %s\n", mpool_strerror(ret)); - exit(1); - } - - exit(0); -} diff --git a/libclamav/mpool.c b/libclamav/mpool.c new file mode 100644 index 000000000..c4d0f70a1 --- /dev/null +++ b/libclamav/mpool.c @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2008 Sourcefire, Inc. + * + * Authors: Alberto Wu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* a naive pool allocator */ + +#if HAVE_CONFIG_H +#include "clamav-config.h" +#endif + +#ifdef USE_MPOOL + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#if HAVE_STRING_H +#include +#endif +#include +#include + + +/* #define DEBUGMPOOL */ +#ifdef DEBUGMPOOL +#include +FILE *lfd = NULL; +#define spam(...) fprintf(lfd, __VA_ARGS__) +#else +#define spam +#endif + +#include "mpool.h" + +//#define MIN_FRAGSIZE 4096 /* 1m2.282s */ +//#define MIN_FRAGSIZE 8192 /* 0m46.652s */ +//#define MIN_FRAGSIZE 16384 /* 0m8.365s */ +//#define MIN_FRAGSIZE 32768 /* 0m3.788s */ +//#define MIN_FRAGSIZE 65536 /* 0m2.759s */ +//#define MIN_FRAGSIZE 131072 /* 0m2.445s */ +#define MIN_FRAGSIZE 262144 /* 0m2.343s */ +//#define MIN_FRAGSIZE 524288 /* 0m2.387s */ +//#define MIN_FRAGSIZE 1048576 /* 0m2.392s */ +//#define MIN_FRAGSIZE 2097152 /* 0m2.402s */ + + +struct FRAG { + struct FRAG *next; + unsigned int sbits; + void *fake; +}; +#define FRAG_OVERHEAD (offsetof(struct FRAG, fake)) + + +static unsigned int align_to_pagesize(struct MP *mp, unsigned int size) { + return (size / mp->psize + (size % mp->psize != 0)) * mp->psize; +} +static unsigned int align_to_voidptr(unsigned int size) { + return (size / sizeof(void *) + (size % sizeof(void *) != 0)) * sizeof(void *); +} + +/* FIXME: use instead a bit2size table so we can spare bits and offer a better granularity */ +static unsigned int to_bits(unsigned int size) { + unsigned int i; + for(i=0; i<32; i++) + if((unsigned int)1<= size) return i; + return i; /* NOTREACHED */ +} +static unsigned int from_bits(unsigned int bits) { + return 1<%p - size %u out of %u\n", mp_p, (void*)mp_p + mp.mpm.size, mp.mpm.usize, mp.mpm.size); + return mp_p; +} + +void mp_destroy(struct MP *mp) { + struct MPMAP *mpm_next = mp->mpm.next, *mpm; + close(mp->fd); + while((mpm = mpm_next)) { + mpm_next = mpm->next; + munmap((void *)mpm, mpm->size); + } + munmap((void *)mp, mp->mpm.size + align_to_voidptr(sizeof(mp))); + spam("Map destroyed @ %p\n", mp); +} + +void mp_flush(struct MP *mp) { + struct MPMAP *mpm_next = mp->mpm.next, *mpm; + while((mpm = mpm_next)) { + mpm_next = mpm->next; + munmap((void *)mpm + align_to_pagesize(mp, mpm->usize), mpm->size - align_to_pagesize(mp, mpm->usize)); + mpm->size = mpm->usize = align_to_pagesize(mp, mpm->usize); + } + munmap(&mp->mpm + align_to_pagesize(mp, mp->mpm.usize + align_to_voidptr(sizeof(mp))), mp->mpm.size - align_to_pagesize(mp, mp->mpm.usize + align_to_voidptr(sizeof(mp)))); + mp->mpm.size = mp->mpm.usize; + spam("Map flushed @ %p\n", mp); +} + +void check_all(struct MP *mp) { + struct MPMAP *mpm = &mp->mpm; + while(mpm) { + volatile unsigned char *c = (unsigned char *)mpm; + unsigned int len = mpm->size; + spam("checking object %p - size %u\n", mpm, len); + while (len--) { + c[len]; + } + mpm=mpm->next; + } +} + +void *mp_malloc(struct MP *mp, size_t size) { + unsigned int i, j, needed = align_to_voidptr(size + FRAG_OVERHEAD); + const unsigned int sbits = to_bits(needed); + struct FRAG *f = NULL; + struct MPMAP *mpm = &mp->mpm; + + // check_all(mp); + if (!size) return NULL; + + j = sbits+2; + if (j<7) j = 7; + if (j > 32) j = 32; + + for (i=sbits; iavail[i])) break; + + /* Case 1: We have a free'd frag */ + if(f) { + spam("malloc %p size %u (freed)\n"), f, size; + mp->avail[i] = f->next; + return &f->fake; + } + + needed = from_bits(sbits); + + /* Case 2: We have nuff room available for this frag already */ + while(mpm) { + if(mpm->size - mpm->usize >= needed) { + f = (struct FRAG *)((void *)mpm + mpm->usize); + spam("malloc %p size %u (hole)\n", f, size); + mpm->usize += needed; + f->sbits = sbits; + return &f->fake; + } + mpm = mpm->next; + } + + /* Case 3: We allocate more */ + if (needed + align_to_voidptr(sizeof(*mpm)) > MIN_FRAGSIZE) + i = align_to_pagesize(mp, needed + align_to_voidptr(sizeof(*mpm))); + else + i = align_to_pagesize(mp, MIN_FRAGSIZE); + + if ((mpm = (struct MPMAP *)mmap(NULL, i, PROT_READ | PROT_WRITE, MAP_PRIVATE, mp->fd, mp->top)) == MAP_FAILED) { + spam("failed to alloc %u bytes (%u requested)\n", i, size); + return NULL; + } + mp->top += i; + mpm->size = i; + mpm->usize = needed + align_to_voidptr(sizeof(*mpm)); + mpm->next = mp->mpm.next; + mp->mpm.next = mpm; + f = (struct FRAG *)((void *)mpm + align_to_voidptr(sizeof(*mpm))); + spam("malloc %p size %u (new map)\n", f, size); + f->sbits = sbits; + return &f->fake; +} + +void mp_free(struct MP *mp, void *ptr) { + struct FRAG *f = (struct FRAG *)(ptr - FRAG_OVERHEAD); + if (!ptr) return; + + f->next = mp->avail[f->sbits]; + mp->avail[f->sbits] = f; + spam("free @ %p\n", f); +} + +void *mp_calloc(struct MP *mp, size_t nmemb, size_t size) { + unsigned int needed = nmemb*size; + void *ptr; + + if(!needed) return NULL; + if((ptr = mp_malloc(mp, needed))) + memset(ptr, 0, needed); + return ptr; +} + +void *mp_realloc(struct MP *mp, void *ptr, size_t size) { + struct FRAG *f = (struct FRAG *)(ptr - FRAG_OVERHEAD); + unsigned int csize; + void *new_ptr; + if (!ptr) return mp_malloc(mp, size); + + spam("realloc @ %p (size %u -> %u))\n", f, from_bits(f->sbits), size); + csize = from_bits(f->sbits) - FRAG_OVERHEAD; + if (csize >= size) return ptr; + if (!(new_ptr = mp_malloc(mp, size))) + return NULL; + memcpy(new_ptr, ptr, csize); + mp_free(mp, ptr); + return new_ptr; +} + +void *mp_realloc2(struct MP *mp, void *ptr, size_t size) { + struct FRAG *f = (struct FRAG *)(ptr - FRAG_OVERHEAD); + unsigned int csize; + void *new_ptr; + if (!ptr) return mp_malloc(mp, size); + + spam("realloc @ %p (size %u -> %u))\n", f, from_bits(f->sbits), size); + csize = from_bits(f->sbits) - FRAG_OVERHEAD; + if (csize >= size) return ptr; + if ((new_ptr = mp_malloc(mp, size))) + memcpy(new_ptr, ptr, csize); + mp_free(mp, ptr); + return new_ptr; +} + +#endif /* USE_MPOOL */ diff --git a/libclamav/mpool.h b/libclamav/mpool.h new file mode 100644 index 000000000..c1a5096c7 --- /dev/null +++ b/libclamav/mpool.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2008 Sourcefire, Inc. + * + * Authors: Alberto Wu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef MPOOL_H +#define MPOOL_H + +#ifdef USE_MPOOL +struct MPMAP { + struct MPMAP *next; + unsigned int size; + unsigned int usize; +}; + +struct MP { + int fd; + unsigned int psize; + unsigned int top; + struct FRAG *avail[32]; + struct MPMAP mpm; +}; + +typedef struct MP mp_t; + +mp_t *mp_create(void); +void mp_destroy(mp_t *mp); +void *mp_malloc(mp_t *mp, size_t size); +void mp_free(mp_t *mp, void *ptr); +void *mp_calloc(mp_t *mp, size_t nmemb, size_t size); +void *mp_realloc(mp_t *mp, void *ptr, size_t size); +void *mp_realloc2(mp_t *mp, void *ptr, size_t size); +void mp_flush(mp_t *mp); + +#else /* USE_MPOOL */ + +#define mp_malloc(a, b) cli_malloc(b) +#define mp_free(a, b) free(b) +#define mp_calloc(a, b, c) cli_calloc(b, c) +#define mp_realloc(a, b, c) cli_realloc(b, c) +#define mp_realloc2(a, b, c) cli_realloc2(b, c) + +#endif /* USE_MPOOL */ + +#endif + + diff --git a/libclamav/phish_whitelist.c b/libclamav/phish_whitelist.c index f0e0063e4..ad07d603a 100644 --- a/libclamav/phish_whitelist.c +++ b/libclamav/phish_whitelist.c @@ -45,9 +45,7 @@ #include "phish_whitelist.h" #include "regex_list.h" -#ifdef USE_MPOOL #include "mpool.h" -#endif int whitelist_match(const struct cl_engine* engine,char* real_url,const char* display_url,int hostOnly) { @@ -59,11 +57,9 @@ int whitelist_match(const struct cl_engine* engine,char* real_url,const char* di int init_whitelist(struct cl_engine* engine) { if(engine) { + engine->whitelist_matcher = (struct regex_matcher *) mp_malloc(engine->mempool, sizeof(struct regex_matcher)); #ifdef USE_MPOOL - engine->whitelist_matcher = (struct regex_matcher *) mpool_alloc(engine->mempool, sizeof(struct regex_matcher), NULL); ((struct regex_matcher *)(engine->whitelist_matcher))->mempool = engine->mempool; -#else - engine->whitelist_matcher = (struct regex_matcher *) cli_malloc(sizeof(struct regex_matcher)); #endif if(!engine->whitelist_matcher) return CL_EMEM; @@ -82,11 +78,7 @@ void whitelist_done(struct cl_engine* engine) { if(engine && engine->whitelist_matcher) { regex_list_done(engine->whitelist_matcher); -#ifdef USE_MPOOL - mpool_free(engine->mempool, engine->whitelist_matcher); -#else - free(engine->whitelist_matcher); -#endif + mp_free(engine->mempool, engine->whitelist_matcher); engine->whitelist_matcher = NULL; } } diff --git a/libclamav/phishcheck.c b/libclamav/phishcheck.c index e639f90ce..49eb83018 100644 --- a/libclamav/phishcheck.c +++ b/libclamav/phishcheck.c @@ -52,9 +52,7 @@ #include "md5.h" #include -#ifdef USE_MPOOL #include "mpool.h" -#endif #define DOMAIN_REAL 1 #define DOMAIN_DISPLAY 0 @@ -861,11 +859,7 @@ int phishing_init(struct cl_engine* engine) { struct phishcheck* pchk; if(!engine->phishcheck) { -#ifdef USE_MPOOL - pchk = engine->phishcheck = mpool_alloc(engine->mempool, sizeof(struct phishcheck), NULL); -#else - pchk = engine->phishcheck = cli_malloc(sizeof(struct phishcheck)); -#endif + pchk = engine->phishcheck = mp_malloc(engine->mempool, sizeof(struct phishcheck)); if(!pchk) return CL_EMEM; pchk->is_disabled=1; @@ -883,11 +877,7 @@ int phishing_init(struct cl_engine* engine) cli_dbgmsg("Initializing phishcheck module\n"); if(build_regex(&pchk->preg_numeric,numeric_url_regex,1)) { -#ifdef USE_MPOOL - mpool_free(engine->mempool, pchk); -#else - free(pchk); -#endif + mp_free(engine->mempool, pchk); engine->phishcheck = NULL; return CL_EFORMAT; } @@ -907,11 +897,7 @@ void phishing_done(struct cl_engine* engine) domainlist_done(engine); if(pchk) { cli_dbgmsg("Freeing phishcheck struct\n"); -#ifdef USE_MPOOL - mpool_free(engine->mempool, pchk); -#else - free(pchk); -#endif + mp_free(engine->mempool, pchk); } cli_dbgmsg("Phishcheck cleaned up\n"); } diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 703e02243..0c323b128 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -67,9 +67,7 @@ #include #endif -#ifdef USE_MPOOL #include "mpool.h" -#endif #ifdef CL_THREAD_SAFE # include @@ -283,11 +281,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex } } else { -#ifdef USE_MPOOL - bm_new = (struct cli_bm_patt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_bm_patt), NULL); -#else - bm_new = (struct cli_bm_patt *) cli_calloc(1, sizeof(struct cli_bm_patt)); -#endif + bm_new = (struct cli_bm_patt *) mp_calloc(root->mempool, 1, sizeof(struct cli_bm_patt)); if(!bm_new) return CL_EMEM; @@ -296,7 +290,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex unsigned char *mpoolhexsig = (unsigned char *) cli_hex2str(hexsig); if(mpoolhexsig) { unsigned int mpoolhexsigsz = strlen(hexsig) / 2 + 1; - if((bm_new->pattern = mpool_alloc(root->mempool, mpoolhexsigsz, NULL))) + if((bm_new->pattern = mp_malloc(root->mempool, mpoolhexsigsz))) memcpy(bm_new->pattern, mpoolhexsig, mpoolhexsigsz); free(mpoolhexsig); } else bm_new->pattern = NULL; @@ -305,11 +299,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex bm_new->pattern = (unsigned char *) cli_hex2str(hexsig); #endif if(!bm_new->pattern) { -#ifdef USE_MPOOL - mpool_free(root->mempool, bm_new); -#else - free(bm_new); -#endif + mp_free(root->mempool, bm_new); return CL_EMALFDB; } bm_new->length = strlen(hexsig) / 2; @@ -318,7 +308,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex { char *mpoolvirname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); if(mpoolvirname) { - if((bm_new->virname = mpool_alloc(root->mempool, strlen(mpoolvirname) + 1, NULL))) + if((bm_new->virname = mp_malloc(root->mempool, strlen(mpoolvirname) + 1))) strcpy(bm_new->virname, mpoolvirname); free(mpoolvirname); } else bm_new->virname = NULL; @@ -327,33 +317,22 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex bm_new->virname = cli_virname((char *) virname, options & CL_DB_OFFICIAL, 0); #endif if(!bm_new->virname) { -#ifdef USE_MPOOL - mpool_free(root->mempool, bm_new->pattern); - mpool_free(root->mempool, bm_new); -#else - free(bm_new->pattern); - free(bm_new); -#endif + mp_free(root->mempool, bm_new->pattern); + mp_free(root->mempool, bm_new); return CL_EMEM; } if(offset) { #ifdef USE_MPOOL - if((bm_new->offset = mpool_alloc(root->mempool, strlen(offset) + 1, NULL))) + if((bm_new->offset = mp_malloc(root->mempool, strlen(offset) + 1))) strcpy(bm_new->offset, offset); #else bm_new->offset = cli_strdup(offset); #endif if(!bm_new->offset) { -#ifdef USE_MPOOL - mpool_free(root->mempool, bm_new->pattern); - mpool_free(root->mempool, bm_new->virname); - mpool_free(root->mempool, bm_new); -#else - free(bm_new->pattern); - free(bm_new->virname); - free(bm_new); -#endif + mp_free(root->mempool, bm_new->pattern); + mp_free(root->mempool, bm_new->virname); + mp_free(root->mempool, bm_new); return CL_EMEM; } } @@ -365,15 +344,9 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex if((ret = cli_bm_addpatt(root, bm_new))) { cli_errmsg("cli_parse_add(): Problem adding signature (4).\n"); -#ifdef USE_MPOOL - mpool_free(root->mempool, bm_new->pattern); - mpool_free(root->mempool, bm_new->virname); - mpool_free(root->mempool, bm_new); -#else - free(bm_new->pattern); - free(bm_new->virname); - free(bm_new); -#endif + mp_free(root->mempool, bm_new->pattern); + mp_free(root->mempool, bm_new->virname); + mp_free(root->mempool, bm_new); return ret; } } @@ -398,15 +371,12 @@ int cli_initengine(struct cl_engine **engine, unsigned int options) (*engine)->refcount = 1; #ifdef USE_MPOOL - if(!((*engine)->mempool = mpool_open(MPOOL_FLAG_HEAVY_PACKING | MPOOL_FLAG_BEST_FIT, 0, NULL, NULL))) { + if(!((*engine)->mempool = mp_create())) { cli_errmsg("Can't allocate memory for memory pool!\n"); return CL_EMEM; } - - (*engine)->root = mpool_calloc((*engine)->mempool, CLI_MTARGETS, sizeof(struct cli_matcher *), NULL); -#else - (*engine)->root = cli_calloc(CLI_MTARGETS, sizeof(struct cli_matcher *)); #endif + (*engine)->root = mp_calloc((*engine)->mempool, CLI_MTARGETS, sizeof(struct cli_matcher *)); if(!(*engine)->root) { /* no need to free previously allocated memory here */ cli_errmsg("Can't allocate memory for roots!\n"); @@ -440,11 +410,9 @@ static int cli_initroots(struct cl_engine *engine, unsigned int options) for(i = 0; i < CLI_MTARGETS; i++) { if(!engine->root[i]) { cli_dbgmsg("Initializing engine->root[%d]\n", i); + root = engine->root[i] = (struct cli_matcher *) mp_calloc(engine->mempool, 1, sizeof(struct cli_matcher)); #ifdef USE_MPOOL - root = engine->root[i] = (struct cli_matcher *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_matcher), NULL); root->mempool = engine->mempool; -#else - root = engine->root[i] = (struct cli_matcher *) cli_calloc(1, sizeof(struct cli_matcher)); #endif if(!root) { cli_errmsg("cli_initroots: Can't allocate memory for cli_matcher\n"); @@ -867,11 +835,7 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) switch(apt->type) { case CLI_TDB_UINT: off[i] = cnt = tdb->cnt[CLI_TDB_UINT]++; -#ifdef USE_MPOOL - tdb->val = (uint32_t *) mpool_resize2(tdb->mempool, tdb->val, tdb->cnt[CLI_TDB_UINT] * sizeof(uint32_t), NULL); -#else - tdb->val = (uint32_t *) cli_realloc2(tdb->val, tdb->cnt[CLI_TDB_UINT] * sizeof(uint32_t)); -#endif + tdb->val = (uint32_t *) mp_realloc2(tdb->mempool, tdb->val, tdb->cnt[CLI_TDB_UINT] * sizeof(uint32_t)); if(!tdb->val) { tdb->cnt[CLI_TDB_UINT] = 0; return -1; @@ -887,11 +851,7 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) *pt2++ = 0; off[i] = cnt = tdb->cnt[CLI_TDB_RANGE]; tdb->cnt[CLI_TDB_RANGE] += 2; -#ifdef USE_MPOOL - tdb->range = (uint32_t *) mpool_resize2(tdb->mempool, tdb->range, tdb->cnt[CLI_TDB_RANGE] * sizeof(uint32_t), NULL); -#else - tdb->range = (uint32_t *) cli_realloc2(tdb->range, tdb->cnt[CLI_TDB_RANGE] * sizeof(uint32_t)); -#endif + tdb->range = (uint32_t *) mp_realloc2(tdb->mempool, tdb->range, tdb->cnt[CLI_TDB_RANGE] * sizeof(uint32_t)); if(!tdb->range) { tdb->cnt[CLI_TDB_RANGE] = 0; return -1; @@ -907,11 +867,7 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) } off[i] = cnt = tdb->cnt[CLI_TDB_RANGE]; tdb->cnt[CLI_TDB_RANGE] += 3; -#ifdef USE_MPOOL - tdb->range = (uint32_t *) mpool_resize2(tdb->mempool, tdb->range, tdb->cnt[CLI_TDB_RANGE] * sizeof(uint32_t), NULL); -#else - tdb->range = (uint32_t *) cli_realloc2(tdb->range, tdb->cnt[CLI_TDB_RANGE] * sizeof(uint32_t)); -#endif + tdb->range = (uint32_t *) mp_realloc2(tdb->mempool, tdb->range, tdb->cnt[CLI_TDB_RANGE] * sizeof(uint32_t)); if(!tdb->range) { tdb->cnt[CLI_TDB_RANGE] = 0; return -1; @@ -928,11 +884,7 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) case CLI_TDB_STR: off[i] = cnt = tdb->cnt[CLI_TDB_STR]; tdb->cnt[CLI_TDB_STR] += strlen(pt) + 1; -#ifdef USE_MPOOL - tdb->str = (char *) mpool_resize2(tdb->mempool, tdb->str, tdb->cnt[CLI_TDB_STR] * sizeof(char), NULL); -#else - tdb->str = (char *) cli_realloc2(tdb->str, tdb->cnt[CLI_TDB_STR] * sizeof(char)); -#endif + tdb->str = (char *) mp_realloc2(tdb->mempool, tdb->str, tdb->cnt[CLI_TDB_STR] * sizeof(char)); if(!tdb->str) { cli_errmsg("lsigattribs: Can't allocate memory for tdb->str\n"); return -1; @@ -974,24 +926,14 @@ static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb) return 0; } -#ifdef USE_MPOOL #define FREE_TDB(x) do { \ if(x.cnt[CLI_TDB_UINT]) \ - mpool_free(x.mempool, x.val); \ + mp_free(x.mempool, x.val); \ if(x.cnt[CLI_TDB_RANGE]) \ - mpool_free(x.mempool, x.range); \ + mp_free(x.mempool, x.range); \ if(x.cnt[CLI_TDB_STR]) \ - mpool_free(x.mempool, x.str); \ + mp_free(x.mempool, x.str); \ } while(0); -#else -#define FREE_TDB(x) \ - if(x.cnt[CLI_TDB_UINT]) \ - free(x.val); \ - if(x.cnt[CLI_TDB_RANGE]) \ - free(x.range); \ - if(x.cnt[CLI_TDB_STR]) \ - free(x.str); -#endif #define LDB_TOKENS 67 static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio, const char *dbname) @@ -1093,11 +1035,8 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, } root = (*engine)->root[tdb.target[0]]; -#ifdef USE_MPOOL - lsig = (struct cli_ac_lsig *) mpool_calloc((*engine)->mempool, 1, sizeof(struct cli_ac_lsig), NULL); -#else - lsig = (struct cli_ac_lsig *) cli_calloc(1, sizeof(struct cli_ac_lsig)); -#endif + + lsig = (struct cli_ac_lsig *) mp_calloc((*engine)->mempool, 1, sizeof(struct cli_ac_lsig)); if(!lsig) { cli_errmsg("cli_loadldb: Can't allocate memory for lsig\n"); FREE_TDB(tdb); @@ -1105,7 +1044,7 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, break; } #ifdef USE_MPOOL - if((lsig->logic = mpool_alloc((*engine)->mempool, strlen(logic)+1, NULL))) + if((lsig->logic = mp_malloc((*engine)->mempool, strlen(logic)+1))) strcpy(lsig->logic, logic); #else lsig->logic = cli_strdup(logic); @@ -1114,11 +1053,7 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, cli_errmsg("cli_loadldb: Can't allocate memory for lsig->logic\n"); FREE_TDB(tdb); ret = CL_EMEM; -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, lsig); -#else - free(lsig); -#endif + mp_free((*engine)->mempool, lsig); break; } @@ -1126,20 +1061,12 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, memcpy(&lsig->tdb, &tdb, sizeof(tdb)); root->ac_lsigs++; -#ifdef USE_MPOOL - newtable = (struct cli_ac_lsig **) mpool_resize((*engine)->mempool, root->ac_lsigtable, root->ac_lsigs * sizeof(struct cli_ac_lsig *), NULL); -#else - newtable = (struct cli_ac_lsig **) cli_realloc(root->ac_lsigtable, root->ac_lsigs * sizeof(struct cli_ac_lsig *)); -#endif + newtable = (struct cli_ac_lsig **) mp_realloc((*engine)->mempool, root->ac_lsigtable, root->ac_lsigs * sizeof(struct cli_ac_lsig *)); if(!newtable) { root->ac_lsigs--; cli_errmsg("cli_loadldb: Can't realloc root->ac_lsigtable\n"); FREE_TDB(tdb); -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, lsig); -#else - free(lsig); -#endif + mp_free((*engine)->mempool, lsig); ret = CL_EMEM; break; } @@ -1264,11 +1191,7 @@ static int cli_loadftm(FILE *fs, struct cl_engine **engine, unsigned int options break; } else if(atoi(tokens[0]) == 0) { /* memcmp() */ -#ifdef USE_MPOOL - new = (struct cli_ftype *) mpool_alloc((*engine)->mempool, sizeof(struct cli_ftype), NULL); -#else - new = (struct cli_ftype *) cli_malloc(sizeof(struct cli_ftype)); -#endif + new = (struct cli_ftype *) mp_malloc((*engine)->mempool, sizeof(struct cli_ftype)); if(!new) { ret = CL_EMEM; break; @@ -1280,7 +1203,7 @@ static int cli_loadftm(FILE *fs, struct cl_engine **engine, unsigned int options unsigned char *mpoolmagic = cli_hex2str(tokens[2]); if(mpoolmagic) { unsigned int mpoolmagicsz = strlen(tokens[2]) / 2 + 1; - if((new->magic = mpool_alloc((*engine)->mempool, mpoolmagicsz, NULL))) + if((new->magic = mp_malloc((*engine)->mempool, mpoolmagicsz))) memcpy(new->magic, mpoolmagic, mpoolmagicsz); free(mpoolmagic); } else new->magic = NULL; @@ -1291,28 +1214,19 @@ static int cli_loadftm(FILE *fs, struct cl_engine **engine, unsigned int options if(!new->magic) { cli_errmsg("cli_loadftm: Can't decode the hex string\n"); ret = CL_EMALFDB; -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new); -#else - free(new); -#endif + mp_free((*engine)->mempool, new); break; } new->length = strlen(tokens[2]) / 2; #ifdef USE_MPOOL - if((new->tname = mpool_alloc((*engine)->mempool, strlen(tokens[3])+1, NULL))) + if((new->tname = mp_malloc((*engine)->mempool, strlen(tokens[3])+1))) strcpy(new->tname, tokens[3]); #else new->tname = cli_strdup(tokens[3]); #endif if(!new->tname) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->magic); - mpool_free((*engine)->mempool, new); -#else - free(new->magic); - free(new); -#endif + mp_free((*engine)->mempool, new->magic); + mp_free((*engine)->mempool, new); ret = CL_EMEM; break; } @@ -1367,11 +1281,7 @@ static int cli_loadign(FILE *fs, struct cl_engine **engine, unsigned int options while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) { line++; cli_chomp(buffer); -#ifdef USE_MPOOL - new = (struct cli_ignsig *) mpool_calloc((*engine)->mempool, 1, sizeof(struct cli_ignsig), NULL); -#else - new = (struct cli_ignsig *) cli_calloc(1, sizeof(struct cli_ignsig)); -#endif + new = (struct cli_ignsig *) mp_calloc((*engine)->mempool, 1, sizeof(struct cli_ignsig)); if(!new) { ret = CL_EMEM; break; @@ -1381,7 +1291,7 @@ static int cli_loadign(FILE *fs, struct cl_engine **engine, unsigned int options { unsigned char *mpooldbname = cli_strtok(buffer, 0, ":"); if(mpooldbname) { - if((new->dbname = mpool_alloc((*engine)->mempool, strlen(mpooldbname) + 1, NULL))) + if((new->dbname = mp_malloc((*engine)->mempool, strlen(mpooldbname) + 1))) strcpy(new->dbname, mpooldbname); free(mpooldbname); } else new->dbname = NULL; @@ -1390,23 +1300,14 @@ static int cli_loadign(FILE *fs, struct cl_engine **engine, unsigned int options new->dbname = cli_strtok(buffer, 0, ":"); #endif if(!new->dbname) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new); -#else - free(new); -#endif + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } if(!(pt = cli_strtok(buffer, 1, ":"))) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->dbname); - mpool_free((*engine)->mempool, new); -#else - free(new->dbname); - free(new); -#endif + mp_free((*engine)->mempool, new->dbname); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } else { @@ -1421,7 +1322,7 @@ static int cli_loadign(FILE *fs, struct cl_engine **engine, unsigned int options { unsigned char *mpoolsigname = cli_strtok(buffer, 2, ":"); if(mpoolsigname) { - if((new->signame = mpool_alloc((*engine)->mempool, strlen(mpoolsigname) + 1, NULL))) + if((new->signame = mp_malloc((*engine)->mempool, strlen(mpoolsigname) + 1))) strcpy(new->signame, mpoolsigname); free(mpoolsigname); } else new->signame = NULL; @@ -1430,13 +1331,8 @@ static int cli_loadign(FILE *fs, struct cl_engine **engine, unsigned int options new->signame = cli_strtok(buffer, 2, ":"); #endif if(!new->signame) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->dbname); - mpool_free((*engine)->mempool, new); -#else - free(new->dbname); - free(new); -#endif + mp_free((*engine)->mempool, new->dbname); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } @@ -1467,15 +1363,9 @@ static void cli_freeign(struct cl_engine *engine) while(ignored->list) { pt = ignored->list; ignored->list = ignored->list->next; -#ifdef USE_MPOOL - mpool_free(engine->mempool, pt->dbname); - mpool_free(engine->mempool, pt->signame); - mpool_free(engine->mempool,pt); -#else - free(pt->dbname); - free(pt->signame); - free(pt); -#endif + mp_free(engine->mempool, pt->dbname); + mp_free(engine->mempool, pt->signame); + mp_free(engine->mempool,pt); } hashset_destroy(&ignored->hs); free(engine->ignored); @@ -1499,23 +1389,11 @@ static int cli_md5db_init(struct cl_engine **engine, unsigned int mode) if(mode == MD5_HDB) { -#ifdef USE_MPOOL - bm = (*engine)->md5_hdb = (struct cli_matcher *) mpool_calloc((*engine)->mempool, sizeof(struct cli_matcher), 1, NULL); -#else - bm = (*engine)->md5_hdb = (struct cli_matcher *) cli_calloc(sizeof(struct cli_matcher), 1); -#endif + bm = (*engine)->md5_hdb = (struct cli_matcher *) mp_calloc((*engine)->mempool, sizeof(struct cli_matcher), 1); } else if(mode == MD5_MDB) { -#ifdef USE_MPOOL - bm = (*engine)->md5_mdb = (struct cli_matcher *) mpool_calloc((*engine)->mempool, sizeof(struct cli_matcher), 1, NULL); -#else - bm = (*engine)->md5_mdb = (struct cli_matcher *) cli_calloc(sizeof(struct cli_matcher), 1); -#endif + bm = (*engine)->md5_mdb = (struct cli_matcher *) mp_calloc((*engine)->mempool, sizeof(struct cli_matcher), 1); } else { -#ifdef USE_MPOOL - bm = (*engine)->md5_fp = (struct cli_matcher *) mpool_calloc((*engine)->mempool, sizeof(struct cli_matcher), 1, NULL); -#else - bm = (*engine)->md5_fp = (struct cli_matcher *) cli_calloc(sizeof(struct cli_matcher), 1); -#endif + bm = (*engine)->md5_fp = (struct cli_matcher *) mp_calloc((*engine)->mempool, sizeof(struct cli_matcher), 1); } if(!bm) @@ -1578,22 +1456,14 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, if((*engine)->ignored && cli_chkign((*engine)->ignored, dbname, line, pt)) continue; -#ifdef USE_MPOOL - new = (struct cli_bm_patt *) mpool_calloc((*engine)->mempool, 1, sizeof(struct cli_bm_patt), NULL); -#else - new = (struct cli_bm_patt *) cli_calloc(1, sizeof(struct cli_bm_patt)); -#endif + new = (struct cli_bm_patt *) mp_calloc((*engine)->mempool, 1, sizeof(struct cli_bm_patt)); if(!new) { ret = CL_EMEM; break; } if(!(pt = tokens[md5_field])) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new); -#else - free(new); -#endif + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } @@ -1602,14 +1472,14 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, if(strlen(pt) == 32) { unsigned char *mpoolhex = (unsigned char *) cli_hex2str(pt); if(mpoolhex) { - if((new->pattern = mpool_alloc((*engine)->mempool, 17, NULL))) + if((new->pattern = mp_malloc((*engine)->mempool, 17))) memcpy(new->pattern, mpoolhex, 17); free(mpoolhex); } else new->pattern = NULL; } else new->pattern = NULL; if(new->pattern == NULL) { cli_errmsg("cli_loadmd5: Malformed MD5 string at line %u\n", line); - mpool_free((*engine)->mempool, new); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } @@ -1624,13 +1494,8 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, new->length = 16; if(!(pt = tokens[size_field])) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->pattern); - mpool_free((*engine)->mempool, new); -#else - free(new->pattern); - free(new); -#endif + mp_free((*engine)->mempool, new->pattern); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } @@ -1640,7 +1505,7 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, { char *mpoolvname = cli_virname((char *) tokens[2], options & CL_DB_OFFICIAL, 0); if(mpoolvname) { - if((new->virname = mpool_alloc((*engine)->mempool, strlen(mpoolvname) + 1, NULL))) + if((new->virname = mp_malloc((*engine)->mempool, strlen(mpoolvname) + 1))) strcpy(new->virname, mpoolvname); free(mpoolvname); } else new->virname = NULL; @@ -1649,29 +1514,17 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, new->virname = cli_virname((char *) tokens[2], options & CL_DB_OFFICIAL, 0); #endif if(!new->virname) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->pattern); - mpool_free((*engine)->mempool, new); -#else - free(new->pattern); - free(new); -#endif + mp_free((*engine)->mempool, new->pattern); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } MD5_DB; if(!db && (ret = cli_md5db_init(engine, mode))) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->pattern); - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - - free(new->pattern); - free(new->virname); - free(new); -#endif + mp_free((*engine)->mempool, new->pattern); + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); break; } else { MD5_DB; @@ -1679,16 +1532,9 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, if((ret = cli_bm_addpatt(db, new))) { cli_errmsg("cli_loadmd5: Error adding BM pattern\n"); -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->pattern); - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - - free(new->pattern); - free(new->virname); - free(new); -#endif + mp_free((*engine)->mempool, new->pattern); + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); break; } @@ -1740,11 +1586,7 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, cli_chomp(buffer); -#ifdef USE_MPOOL - new = (struct cli_meta_node *) mpool_calloc((*engine)->mempool, 1, sizeof(struct cli_meta_node), NULL); -#else - new = (struct cli_meta_node *) cli_calloc(1, sizeof(struct cli_meta_node)); -#endif + new = (struct cli_meta_node *) mp_calloc((*engine)->mempool, 1, sizeof(struct cli_meta_node)); if(!new) { ret = CL_EMEM; break; @@ -1754,7 +1596,7 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, { char *mpoolvname = cli_virname(cli_strtok(buffer, 0, ":"), options & CL_DB_OFFICIAL, 1); if(mpoolvname) { - if((new->virname = mpool_alloc((*engine)->mempool, strlen(mpoolvname) + 1, NULL))) + if((new->virname = mp_malloc((*engine)->mempool, strlen(mpoolvname) + 1))) strcpy(new->virname, mpoolvname); free(mpoolvname); } else new->virname = NULL; @@ -1763,34 +1605,20 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, new->virname = cli_virname(cli_strtok(buffer, 0, ":"), options & CL_DB_OFFICIAL, 1); #endif if(!new->virname) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new); -#else - free(new); -#endif + mp_free((*engine)->mempool, new); ret = CL_EMEM; break; } if((*engine)->ignored && cli_chkign((*engine)->ignored, dbname, line, new->virname)) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - free(new->virname); - free(new); -#endif + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); continue; } if(!(pt = cli_strtok(buffer, 1, ":"))) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - free(new->virname); - free(new); -#endif + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } else { @@ -1802,7 +1630,7 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, { char *mpoolfname = cli_strtok(buffer, 2, ":"); if(mpoolfname) { - if((new->filename = mpool_alloc((*engine)->mempool, strlen(mpoolfname) + 1, NULL))) + if((new->filename = mp_malloc((*engine)->mempool, strlen(mpoolfname) + 1))) strcpy(new->filename, mpoolfname); free(mpoolfname); } else new->filename = NULL; @@ -1811,36 +1639,21 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, new->filename = cli_strtok(buffer, 2, ":"); #endif if(!new->filename) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - free(new->virname); - free(new); -#endif + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } else { if(!strcmp(new->filename, "*")) { -#ifdef USE_MPOOL - mpool_free((*engine)->mempool, new->filename); -#else - free(new->filename); -#endif + mp_free((*engine)->mempool, new->filename); new->filename = NULL; } } if(!(pt = cli_strtok(buffer, 3, ":"))) { -#ifdef USE_MPOOL - if(new->filename) mpool_free((*engine)->mempool, new->filename); - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - if(new->filename) free(new->filename); - free(new->virname); - free(new); -#endif + if(new->filename) mp_free((*engine)->mempool, new->filename); + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } else { @@ -1852,15 +1665,9 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, } if(!(pt = cli_strtok(buffer, 4, ":"))) { -#ifdef USE_MPOOL - if(new->filename) mpool_free((*engine)->mempool, new->filename); - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - if(new->filename) free(new->filename); - free(new->virname); - free(new); -#endif + if(new->filename) mp_free((*engine)->mempool, new->filename); + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } else { @@ -1872,15 +1679,9 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, } if(!(pt = cli_strtok(buffer, 5, ":"))) { -#ifdef USE_MPOOL - if(new->filename) mpool_free((*engine)->mempool, new->filename); - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - if(new->filename) free(new->filename); - free(new->virname); - free(new); -#endif + if(new->filename) mp_free((*engine)->mempool, new->filename); + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } else { @@ -1898,15 +1699,9 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, } if(!(pt = cli_strtok(buffer, 6, ":"))) { -#ifdef USE_MPOOL - if(new->filename) mpool_free((*engine)->mempool, new->filename); - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - if(new->filename) free(new->filename); - free(new->virname); - free(new); -#endif + if(new->filename) mp_free((*engine)->mempool, new->filename); + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } else { @@ -1918,15 +1713,9 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, } if(!(pt = cli_strtok(buffer, 7, ":"))) { -#ifdef USE_MPOOL - if(new->filename) mpool_free((*engine)->mempool, new->filename); - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - if(new->filename) free(new->filename); - free(new->virname); - free(new); -#endif + if(new->filename) mp_free((*engine)->mempool, new->filename); + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } else { @@ -1938,15 +1727,9 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, } if(!(pt = cli_strtok(buffer, 8, ":"))) { -#ifdef USE_MPOOL - if(new->filename) mpool_free((*engine)->mempool, new->filename); - mpool_free((*engine)->mempool, new->virname); - mpool_free((*engine)->mempool, new); -#else - if(new->filename) free(new->filename); - free(new->virname); - free(new); -#endif + if(new->filename) mp_free((*engine)->mempool, new->filename); + mp_free((*engine)->mempool, new->virname); + mp_free((*engine)->mempool, new); ret = CL_EMALFDB; break; } else { @@ -2487,9 +2270,6 @@ void cl_free(struct cl_engine *engine) #ifdef CL_THREAD_SAFE pthread_mutex_unlock(&cli_ref_mutex); -#endif -#ifdef USE_MPOOL -#define free(X) mpool_free(engine->mempool, X) #endif if(engine->root) { for(i = 0; i < CLI_MTARGETS; i++) { @@ -2499,71 +2279,70 @@ void cl_free(struct cl_engine *engine) cli_ac_free(root); if(root->ac_lsigtable) { for(j = 0; j < root->ac_lsigs; j++) { - free(root->ac_lsigtable[j]->logic); + mp_free(engine->mempool, root->ac_lsigtable[j]->logic); FREE_TDB(root->ac_lsigtable[j]->tdb); - free(root->ac_lsigtable[j]); + mp_free(engine->mempool, root->ac_lsigtable[j]); } - free(root->ac_lsigtable); + mp_free(engine->mempool, root->ac_lsigtable); } - free(root); + mp_free(engine->mempool, root); } } - free(engine->root); + mp_free(engine->mempool, engine->root); } if((root = engine->md5_hdb)) { cli_bm_free(root); - free(root); + mp_free(engine->mempool, root); } if((root = engine->md5_mdb)) { cli_bm_free(root); - free(root->soff); + mp_free(engine->mempool, root->soff); if(root->md5_sizes_hs.capacity) { hashset_destroy(&root->md5_sizes_hs); } - free(root); + mp_free(engine->mempool, root); } if((root = engine->md5_fp)) { cli_bm_free(root); - free(root); + mp_free(engine->mempool, root); } metapt = engine->zip_mlist; while(metapt) { metah = metapt; metapt = metapt->next; - free(metah->virname); + mp_free(engine->mempool, metah->virname); if(metah->filename) - free(metah->filename); - free(metah); + mp_free(engine->mempool, metah->filename); + mp_free(engine->mempool, metah); } metapt = engine->rar_mlist; while(metapt) { metah = metapt; metapt = metapt->next; - free(metah->virname); + mp_free(engine->mempool, metah->virname); if(metah->filename) - free(metah->filename); - free(metah); + mp_free(engine->mempool, metah->filename); + mp_free(engine->mempool, metah); } if(((struct cli_dconf *) engine->dconf)->phishing & PHISHING_CONF_ENGINE) phishing_done(engine); if(engine->dconf) - free(engine->dconf); + mp_free(engine->mempool, engine->dconf); if(engine->pua_cats) - free(engine->pua_cats); + mp_free(engine->mempool, engine->pua_cats); cli_ftfree(engine); cli_freeign(engine); #ifdef USE_MPOOL -#undef free(X) - if(engine->mempool) mpool_close(engine->mempool); -#endif /* USE_MPOOL */ + if(engine->mempool) mp_destroy(engine->mempool); +#endif free(engine); } @@ -2577,7 +2356,7 @@ static void cli_md5db_build(struct cli_matcher* root) { uint32_t *mpoolht; unsigned int mpoolhtsz = root->md5_sizes_hs.count * sizeof(*mpoolht); - root->soff = mpool_alloc(root->mempool, mpoolhtsz, NULL); + root->soff = mp_malloc(root->mempool, mpoolhtsz); root->soff_len = hashset_toarray(&root->md5_sizes_hs, &mpoolht); memcpy(root->soff, mpoolht, mpoolhtsz); free(mpoolht); diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c index 0fc42fd81..5f85467b4 100644 --- a/libclamav/regex_list.c +++ b/libclamav/regex_list.c @@ -58,9 +58,7 @@ #include "jsparse/textbuf.h" #include "regex_suffix.h" -#ifdef USE_MPOOL #include "mpool.h" -#endif /* Prototypes */ static regex_t *new_preg(struct regex_matcher *matcher); @@ -348,7 +346,7 @@ int regex_list_match(struct regex_matcher* matcher,char* real_url,const char* di int init_regex_list(struct regex_matcher* matcher) { #ifdef USE_MPOOL - mpool_t *mp = matcher->mempool; + mp_t *mp = matcher->mempool; #endif int rc; @@ -595,17 +593,9 @@ void regex_list_done(struct regex_matcher* matcher) for(i=0;iregex_cnt;i++) { regex_t *r = matcher->all_pregs[i]; cli_regfree(r); -#ifdef USE_MPOOL - mpool_free(matcher->mempool, r); -#else - free(r); -#endif + mp_free(matcher->mempool, r); } -#ifdef USE_MPOOL - mpool_free(matcher->mempool, matcher->all_pregs); -#else - free(matcher->all_pregs); -#endif + mp_free(matcher->mempool, matcher->all_pregs); } hashtab_free(&matcher->suffix_hash); cli_bm_free(&matcher->md5_hashes); @@ -621,11 +611,7 @@ int is_regex_ok(struct regex_matcher* matcher) static int add_newsuffix(struct regex_matcher *matcher, struct regex_list *info, const char *suffix, size_t len) { struct cli_matcher *root = &matcher->suffixes; -#ifdef USE_MPOOL - struct cli_ac_patt *new = mpool_calloc(matcher->mempool,1,sizeof(*new),NULL); -#else - struct cli_ac_patt *new = cli_calloc(1,sizeof(*new)); -#endif + struct cli_ac_patt *new = mp_calloc(matcher->mempool,1,sizeof(*new)); size_t i; int ret; @@ -647,17 +633,9 @@ static int add_newsuffix(struct regex_matcher *matcher, struct regex_list *info, if(new->length > root->maxpatlen) root->maxpatlen = new->length; -#ifdef USE_MPOOL - new->pattern = mpool_alloc(matcher->mempool, sizeof(new->pattern[0])*len, NULL); -#else - new->pattern = cli_malloc(sizeof(new->pattern[0])*len); -#endif + new->pattern = mp_malloc(matcher->mempool, sizeof(new->pattern[0])*len); if(!new->pattern) { -#ifdef USE_MPOOL - mpool_free(matcher->mempool, new); -#else - free(new); -#endif + mp_free(matcher->mempool, new); return CL_EMEM; } for(i=0;icustomdata = info; new->virname = NULL; if((ret = cli_ac_addpatt(root,new))) { -#ifdef USE_MPOOL - mpool_free(matcher->mempool, new->pattern); - mpool_free(matcher->mempool, new); -#else - free(new->pattern); - free(new); -#endif + mp_free(matcher->mempool, new->pattern); + mp_free(matcher->mempool, new); return ret; } SO_preprocess_add(&matcher->filter, (const unsigned char*)suffix, len); @@ -743,18 +716,10 @@ static size_t reverse_string(char *pattern) static regex_t *new_preg(struct regex_matcher *matcher) { regex_t *r; -#ifdef USE_MPOOL - matcher->all_pregs = mpool_resize(matcher->mempool, matcher->all_pregs, ++matcher->regex_cnt * sizeof(*matcher->all_pregs), NULL); -#else - matcher->all_pregs = cli_realloc(matcher->all_pregs, ++matcher->regex_cnt * sizeof(*matcher->all_pregs)); -#endif + matcher->all_pregs = mp_realloc(matcher->mempool, matcher->all_pregs, ++matcher->regex_cnt * sizeof(*matcher->all_pregs)); if(!matcher->all_pregs) return NULL; -#ifdef USE_MPOOL - r = mpool_alloc(matcher->mempool, sizeof(*r), NULL); -#else - r = cli_malloc(sizeof(*r)); -#endif + r = mp_malloc(matcher->mempool, sizeof(*r)); if(!r) return NULL; matcher->all_pregs[matcher->regex_cnt-1] = r; diff --git a/libclamav/regex_list.h b/libclamav/regex_list.h index c453b5936..f54e8e022 100644 --- a/libclamav/regex_list.h +++ b/libclamav/regex_list.h @@ -29,9 +29,7 @@ #include "matcher.h" #include /* for gzFile */ -#ifdef USE_MPOOL #include "mpool.h" -#endif struct filter { uint32_t B[65536]; @@ -56,7 +54,7 @@ struct regex_matcher { struct filter md5_filter; struct filter filter; #ifdef USE_MPOOL - mpool_t *mempool; + mp_t *mempool; #endif int list_inited:2; int list_loaded:2; From 948644e61984ed6a7910896361f7f3e2a354203c Mon Sep 17 00:00:00 2001 From: aCaB Date: Tue, 28 Oct 2008 20:57:54 +0000 Subject: [PATCH 20/21] tuned granularity - amd64 only (for now) - VIRT 114 / RES 95 git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4300 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/mpool.c | 63 ++++++++++++++++++--------------- libclamav/mpool.h | 90 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 122 insertions(+), 31 deletions(-) diff --git a/libclamav/mpool.c b/libclamav/mpool.c index c4d0f70a1..3ac1a316e 100644 --- a/libclamav/mpool.c +++ b/libclamav/mpool.c @@ -39,7 +39,7 @@ #include -/* #define DEBUGMPOOL */ +#define DEBUGMPOOL #ifdef DEBUGMPOOL #include FILE *lfd = NULL; @@ -50,16 +50,16 @@ FILE *lfd = NULL; #include "mpool.h" -//#define MIN_FRAGSIZE 4096 /* 1m2.282s */ -//#define MIN_FRAGSIZE 8192 /* 0m46.652s */ -//#define MIN_FRAGSIZE 16384 /* 0m8.365s */ -//#define MIN_FRAGSIZE 32768 /* 0m3.788s */ -//#define MIN_FRAGSIZE 65536 /* 0m2.759s */ -//#define MIN_FRAGSIZE 131072 /* 0m2.445s */ +/* #define MIN_FRAGSIZE 4096 /\* 1m2.282s *\/ */ +/* #define MIN_FRAGSIZE 8192 /\* 0m46.652s *\/ */ +/* #define MIN_FRAGSIZE 16384 /\* 0m8.365s *\/ */ +/* #define MIN_FRAGSIZE 32768 /\* 0m3.788s *\/ */ +/* #define MIN_FRAGSIZE 65536 /\* 0m2.759s *\/ */ +/* #define MIN_FRAGSIZE 131072 /\* 0m2.445s *\/ */ #define MIN_FRAGSIZE 262144 /* 0m2.343s */ -//#define MIN_FRAGSIZE 524288 /* 0m2.387s */ -//#define MIN_FRAGSIZE 1048576 /* 0m2.392s */ -//#define MIN_FRAGSIZE 2097152 /* 0m2.402s */ +/* #define MIN_FRAGSIZE 524288 /\* 0m2.387s *\/ */ +/* #define MIN_FRAGSIZE 1048576 /\* 0m2.392s *\/ */ +/* #define MIN_FRAGSIZE 2097152 /\* 0m2.402s *\/ */ struct FRAG { @@ -69,37 +69,44 @@ struct FRAG { }; #define FRAG_OVERHEAD (offsetof(struct FRAG, fake)) +#define align_to_voidptr(size) (((size) / sizeof(void *) + ((size) % sizeof(void *) != 0)) * sizeof(void *)) +#define roundup(size) (FRAG_OVERHEAD + align_to_voidptr(size)) static unsigned int align_to_pagesize(struct MP *mp, unsigned int size) { return (size / mp->psize + (size % mp->psize != 0)) * mp->psize; } -static unsigned int align_to_voidptr(unsigned int size) { - return (size / sizeof(void *) + (size % sizeof(void *) != 0)) * sizeof(void *); -} -/* FIXME: use instead a bit2size table so we can spare bits and offer a better granularity */ static unsigned int to_bits(unsigned int size) { unsigned int i; - for(i=0; i<32; i++) - if((unsigned int)1<= size) return i; + for(i=0; i= size) return i; return i; /* NOTREACHED */ } static unsigned int from_bits(unsigned int bits) { - return 1<= size) return i; */ +/* return i; /\* NOTREACHED *\/ */ +/* } */ +/* static unsigned int from_bits(unsigned int bits) { */ +/* return 1<%p - size %u out of %u\n", mp_p, (void*)mp_p + mp.mpm.size, mp.mpm.usize, mp.mpm.size); @@ -108,7 +115,6 @@ struct MP *mp_create() { void mp_destroy(struct MP *mp) { struct MPMAP *mpm_next = mp->mpm.next, *mpm; - close(mp->fd); while((mpm = mpm_next)) { mpm_next = mpm->next; munmap((void *)mpm, mpm->size); @@ -148,19 +154,21 @@ void *mp_malloc(struct MP *mp, size_t size) { struct FRAG *f = NULL; struct MPMAP *mpm = &mp->mpm; - // check_all(mp); + /* check_all(mp); */ if (!size) return NULL; j = sbits+2; if (j<7) j = 7; if (j > 32) j = 32; + j=sbits; + for (i=sbits; iavail[i])) break; /* Case 1: We have a free'd frag */ if(f) { - spam("malloc %p size %u (freed)\n"), f, size; + spam("malloc %p size %u (freed)\n", f, roundup(size)); mp->avail[i] = f->next; return &f->fake; } @@ -171,7 +179,7 @@ void *mp_malloc(struct MP *mp, size_t size) { while(mpm) { if(mpm->size - mpm->usize >= needed) { f = (struct FRAG *)((void *)mpm + mpm->usize); - spam("malloc %p size %u (hole)\n", f, size); + spam("malloc %p size %u (hole)\n", f, roundup(size)); mpm->usize += needed; f->sbits = sbits; return &f->fake; @@ -185,17 +193,16 @@ void *mp_malloc(struct MP *mp, size_t size) { else i = align_to_pagesize(mp, MIN_FRAGSIZE); - if ((mpm = (struct MPMAP *)mmap(NULL, i, PROT_READ | PROT_WRITE, MAP_PRIVATE, mp->fd, mp->top)) == MAP_FAILED) { + if ((mpm = (struct MPMAP *)mmap(NULL, i, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) { spam("failed to alloc %u bytes (%u requested)\n", i, size); return NULL; } - mp->top += i; mpm->size = i; mpm->usize = needed + align_to_voidptr(sizeof(*mpm)); mpm->next = mp->mpm.next; mp->mpm.next = mpm; f = (struct FRAG *)((void *)mpm + align_to_voidptr(sizeof(*mpm))); - spam("malloc %p size %u (new map)\n", f, size); + spam("malloc %p size %u (new map)\n", f, roundup(size)); f->sbits = sbits; return &f->fake; } diff --git a/libclamav/mpool.h b/libclamav/mpool.h index c1a5096c7..74c533aed 100644 --- a/libclamav/mpool.h +++ b/libclamav/mpool.h @@ -22,6 +22,92 @@ #define MPOOL_H #ifdef USE_MPOOL + +static const unsigned int fragsz[] = { +24, /* (33067) */ +32, /* (93876) */ +40, /* (731459) */ +48, /* (35286) */ +56, /* (6930) */ +64, /* (442013) */ +72, /* (2706) */ +80, /* (2252) */ +88, /* (3631) */ +96, /* (2594) */ +104, /* (3679) */ +112, /* (3697) */ +120, /* (3991) */ +128, /* (5141) */ +136, /* (22458) */ +144, /* (4320) */ +152, /* (4296) */ +160, /* (12177) */ +168, /* (18024) */ +/* 176, /\* (323) *\/ */ +/* 184, /\* (329) *\/ */ +/* 192, /\* (202) *\/ */ +/* 200, /\* (221) *\/ */ +/* 208, /\* (166) *\/ */ +/* 216, /\* (179) *\/ */ +/* 224, /\* (216) *\/ */ +/* 232, /\* (172) *\/ */ +/* 240, /\* (157) *\/ */ +/* 248, /\* (178) *\/ */ +256, /* (133) */ +/* 264, /\* (157) *\/ */ +/* 272, /\* (140) *\/ */ +/* 280, /\* (161) *\/ */ +/* 288, /\* (125) *\/ */ +/* 296, /\* (141) *\/ */ +/* 304, /\* (100) *\/ */ +/* 312, /\* (97) *\/ */ +/* 320, /\* (70) *\/ */ +/* 328, /\* (13) *\/ */ +/* 336, /\* (21) *\/ */ +/* 344, /\* (21) *\/ */ +/* 352, /\* (13) *\/ */ +/* 360, /\* (9) *\/ */ +/* 368, /\* (8) *\/ */ +/* 376, /\* (14) *\/ */ +/* 384, /\* (5) *\/ */ +/* 392, /\* (6) *\/ */ +/* 400, /\* (4) *\/ */ +/* 408, /\* (2) *\/ */ +/* 416, /\* (6) *\/ */ +/* 424, /\* (5) *\/ */ +/* 432, /\* (4) *\/ */ +/* 440, /\* (4) *\/ */ +/* 448, /\* (4) *\/ */ +/* 464, /\* (2) *\/ */ +/* 472, /\* (2) *\/ */ +/* 480, /\* (1) *\/ */ +/* 496, /\* (1) *\/ */ +/* 512, /\* (2) *\/ */ +520, /* (11) */ +/* 536, /\* (1) *\/ */ +/* 544, /\* (2) *\/ */ +/* 552, /\* (1) *\/ */ +/* 584, /\* (3) *\/ */ +/* 600, /\* (1) *\/ */ +/* 624, /\* (1) *\/ */ +/* 656, /\* (1) *\/ */ +/* 784, /\* (2) *\/ */ +1032, /* (11) */ +/* 2056, /\* (14) *\/ */ +2064, /* (7456) */ +4104, /* (14) */ +8200, /* (9) */ +16392, /* (6) */ +32776, /* (4) */ +63512, /* (7) */ +134408, /* (1) */ +507984, /* (7) */ +1051040, /* (1) */ +2097152 +}; + +#define FRAGSBITS (sizeof(fragsz)/sizeof(fragsz[0])) + struct MPMAP { struct MPMAP *next; unsigned int size; @@ -29,10 +115,8 @@ struct MPMAP { }; struct MP { - int fd; unsigned int psize; - unsigned int top; - struct FRAG *avail[32]; + struct FRAG *avail[FRAGSBITS]; struct MPMAP mpm; }; From 0281fb4d9c9f90ec2761bcd2616900709cfc59db Mon Sep 17 00:00:00 2001 From: aCaB Date: Tue, 28 Oct 2008 22:45:31 +0000 Subject: [PATCH 21/21] 32 and 64 bit pools git-svn-id: file:///var/lib/svn/clamav-devel/branches/mpool@4301 77e5149b-7576-45b1-b177-96237e5ba77b --- clamav-config.h.in | 6 + configure | 113 +++++++++++++++--- configure.in | 9 ++ libclamav/mpool.c | 285 +++++++++++++++++++++++++++++++++++++++++---- libclamav/mpool.h | 99 ---------------- 5 files changed, 374 insertions(+), 138 deletions(-) diff --git a/clamav-config.h.in b/clamav-config.h.in index 101e584e6..434306242 100644 --- a/clamav-config.h.in +++ b/clamav-config.h.in @@ -371,12 +371,18 @@ /* The number of bytes in type short */ #undef SIZEOF_SHORT +/* The number of bytes in type void * */ +#undef SIZEOF_VOID_P + /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Support for IPv6 */ #undef SUPPORT_IPv6 +/* enable memory pools */ +#undef USE_MPOOL + /* use syslog */ #undef USE_SYSLOG diff --git a/configure b/configure index 230e4c287..f87e4c3b2 100755 --- a/configure +++ b/configure @@ -1515,6 +1515,7 @@ Optional Features: --disable-libtool-lock avoid locking (might break parallel builds) --disable-gcc-vcheck do not check for buggy gcc version --enable-experimental enable experimental code + --enable-mempool enable memory pools --enable-check Enable 'check' unit tests (default=auto) --disable-rpath do not hardcode runtime library paths --enable-coverage turn on test coverage [default=no] @@ -4754,13 +4755,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:4757: $ac_compile\"" >&5) + (eval echo "\"\$as_me:4758: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:4760: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:4761: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:4763: output\"" >&5) + (eval echo "\"\$as_me:4764: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5971,7 +5972,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5974 "configure"' > conftest.$ac_ext + echo '#line 5975 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7822,11 +7823,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7825: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7826: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7829: \$? = $ac_status" >&5 + echo "$as_me:7830: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -8161,11 +8162,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8164: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8165: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8168: \$? = $ac_status" >&5 + echo "$as_me:8169: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -8266,11 +8267,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8269: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8270: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8273: \$? = $ac_status" >&5 + echo "$as_me:8274: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -8321,11 +8322,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8324: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8325: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8328: \$? = $ac_status" >&5 + echo "$as_me:8329: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -11077,7 +11078,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11080 "configure" +#line 11081 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11173,7 +11174,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11176 "configure" +#line 11177 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -13238,6 +13239,74 @@ cat >>confdefs.h <<_ACEOF _ACEOF +{ echo "$as_me:$LINENO: checking size of void *" >&5 +echo $ECHO_N "checking size of void *... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_void_p+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include "confdefs.h" +#include + + +int +main () +{ +switch (0) case 0: case (sizeof (void *) == $ac_size):; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sizeof_void_p=$ac_size +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test x$ac_cv_sizeof_void_p != x ; then break; fi +done + +fi + +if test x$ac_cv_sizeof_void_p = x ; then + { { echo "$as_me:$LINENO: error: cannot determine a size for void *" >&5 +echo "$as_me: error: cannot determine a size for void *" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_void_p" >&5 +echo "${ECHO_T}$ac_cv_sizeof_void_p" >&6; } + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_VOID_P $ac_cv_sizeof_void_p +_ACEOF + + # Check whether --enable-experimental was given. if test "${enable_experimental+set}" = set; then @@ -13256,6 +13325,22 @@ _ACEOF VERSION_SUFFIX="$VERSION_SUFFIX-exp" fi +# Check whether --enable-mempool was given. +if test "${enable_mempool+set}" = set; then + enableval=$enable_mempool; enable_mempool=$enableval +else + enable_mempool="no" +fi + + +if test "$enable_mempool" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define USE_MPOOL 1 +_ACEOF + +fi + { echo "$as_me:$LINENO: checking for bind in -lsocket" >&5 echo $ECHO_N "checking for bind in -lsocket... $ECHO_C" >&6; } if test "${ac_cv_lib_socket_bind+set}" = set; then diff --git a/configure.in b/configure.in index 4ac91d8cb..2abc06513 100644 --- a/configure.in +++ b/configure.in @@ -305,6 +305,7 @@ AC_COMPILE_CHECK_SIZEOF([short]) AC_COMPILE_CHECK_SIZEOF([int]) AC_COMPILE_CHECK_SIZEOF([long]) AC_COMPILE_CHECK_SIZEOF([long long]) +AC_COMPILE_CHECK_SIZEOF([void *]) AC_ARG_ENABLE([experimental], [ --enable-experimental enable experimental code], @@ -315,6 +316,14 @@ if test "$enable_experimental" = "yes"; then VERSION_SUFFIX="$VERSION_SUFFIX-exp" fi +AC_ARG_ENABLE([mempool], +[ --enable-mempool enable memory pools], +enable_mempool=$enableval, enable_mempool="no") + +if test "$enable_mempool" = "yes"; then + AC_DEFINE([USE_MPOOL],1,[enable memory pools]) +fi + AC_CHECK_LIB([socket], [bind], [LIBS="$LIBS -lsocket"; CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lsocket"; FRESHCLAM_LIBS="$FRESHCLAM_LIBS -lsocket"; CLAMD_LIBS="$CLAMD_LIBS -lsocket"]) AC_SEARCH_LIBS([gethostent],[nsl], [(LIBS="$LIBS -lnsl"; CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lnsl"; FRESHCLAM_LIBS="$FRESHCLAM_LIBS -lnsl"; CLAMD_LIBS="$CLAMD_LIBS -lnsl")]) diff --git a/libclamav/mpool.c b/libclamav/mpool.c index 3ac1a316e..81f9de2c7 100644 --- a/libclamav/mpool.c +++ b/libclamav/mpool.c @@ -39,7 +39,7 @@ #include -#define DEBUGMPOOL +/* #define DEBUGMPOOL */ #ifdef DEBUGMPOOL #include FILE *lfd = NULL; @@ -61,6 +61,253 @@ FILE *lfd = NULL; /* #define MIN_FRAGSIZE 1048576 /\* 0m2.392s *\/ */ /* #define MIN_FRAGSIZE 2097152 /\* 0m2.402s *\/ */ +#if SIZEOF_VOID_P==8 +static const unsigned int fragsz[] = { +24, /* (33067) */ +32, /* (93970) */ +40, /* (731473) */ +48, /* (35342) */ +56, /* (6967) */ +64, /* (442053) */ +72, /* (2706) */ +80, /* (2281) */ +88, /* (3658) */ +96, /* (2620) */ +104, /* (3705) */ +112, /* (3722) */ +120, /* (4012) */ +128, /* (5161) */ +136, /* (22458) */ +144, /* (4339) */ +152, /* (4315) */ +160, /* (12195) */ +168, /* (18042) */ +/* 176, /\* (341) *\/ */ +/* 184, /\* (329) *\/ */ +192, /* (202) */ +/* 200, /\* (238) *\/ */ +/* 208, /\* (166) *\/ */ +/* 216, /\* (179) *\/ */ +224, /* (216) */ +/* 232, /\* (189) *\/ */ +/* 240, /\* (157) *\/ */ +/* 248, /\* (178) *\/ */ +256, /* (133) */ +/* 264, /\* (157) *\/ */ +/* 272, /\* (140) *\/ */ +/* 280, /\* (161) *\/ */ +/* 288, /\* (125) *\/ */ +/* 296, /\* (141) *\/ */ +304, /* (100) */ +/* 312, /\* (114) *\/ */ +/* 320, /\* (70) *\/ */ +/* 328, /\* (13) *\/ */ +/* 336, /\* (21) *\/ */ +/* 344, /\* (21) *\/ */ +352, /* (13) */ +/* 360, /\* (26) *\/ */ +/* 368, /\* (8) *\/ */ +/* 376, /\* (14) *\/ */ +/* 384, /\* (5) *\/ */ +/* 392, /\* (6) *\/ */ +/* 400, /\* (4) *\/ */ +/* 408, /\* (2) *\/ */ +/* 416, /\* (6) *\/ */ +424, /* (20) */ +/* 432, /\* (4) *\/ */ +/* 440, /\* (4) *\/ */ +/* 448, /\* (4) *\/ */ +/* 464, /\* (2) *\/ */ +/* 472, /\* (2) *\/ */ +/* 480, /\* (1) *\/ */ +/* 496, /\* (1) *\/ */ +/* 512, /\* (2) *\/ */ +528, /* (15) */ +/* 536, /\* (1) *\/ */ +/* 544, /\* (2) *\/ */ +/* 552, /\* (1) *\/ */ +/* 584, /\* (3) *\/ */ +/* 600, /\* (1) *\/ */ +/* 624, /\* (1) *\/ */ +/* 656, /\* (1) *\/ */ +/* 784, /\* (2) *\/ */ +1040, /* (15) */ +/* 2064, /\* (7456) *\/ */ +2072, /* (14) */ +4112, /* (14) */ +8208, /* (9) */ +16400, /* (6) */ +32784, /* (4) */ +63512, /* (7) */ +134408, /* (2) */ +507984, /* (7) */ +1051040, /* (1) */ +2097152 /* FIXME: FAIL HERE OR ABOVE */ +}; + +#else + +static const unsigned int fragsz[] = { +12, /* (2297) */ +16, /* (30785) */ +20, /* (41460) */ +24, /* (69214) */ +28, /* (639488) */ +32, /* (107920) */ +36, /* (454213) */ +40, /* (11497) */ +44, /* (1688) */ +48, /* (5294) */ +52, /* (1496) */ +56, /* (3738) */ +60, /* (1719) */ +64, /* (918) */ +68, /* (956) */ +72, /* (1324) */ +76, /* (1905) */ +80, /* (1745) */ +84, /* (1053) */ +88, /* (1566) */ +92, /* (2081) */ +96, /* (20851) */ +100, /* (1882) */ +104, /* (1848) */ +108, /* (1931) */ +112, /* (2079) */ +116, /* (1736) */ +120, /* (3425) */ +124, /* (2115) */ +128, /* (1298) */ +132, /* (2307) */ +136, /* (2033) */ +140, /* (2837) */ +144, /* (1479) */ +148, /* (1607) */ +152, /* (10587) */ +156, /* (2719) */ +160, /* (15311) */ +164, /* (196) */ +168, /* (145) */ +172, /* (211) */ +176, /* (140) */ +180, /* (116) */ +/* 184, /\* (86) *\/ */ +188, /* (119) */ +192, /* (104) */ +/* 196, /\* (99) *\/ */ +/* 200, /\* (84) *\/ */ +/* 204, /\* (94) *\/ */ +/* 208, /\* (86) *\/ */ +212, /* (136) */ +/* 216, /\* (80) *\/ */ +/* 220, /\* (75) *\/ */ +/* 224, /\* (97) *\/ */ +/* 228, /\* (99) *\/ */ +/* 232, /\* (74) *\/ */ +236, /* (114) */ +/* 240, /\* (64) *\/ */ +/* 244, /\* (73) *\/ */ +/* 248, /\* (62) *\/ */ +/* 252, /\* (71) *\/ */ +/* 256, /\* (69) *\/ */ +/* 260, /\* (85) *\/ */ +/* 264, /\* (71) *\/ */ +268, /* (92) */ +/* 272, /\* (69) *\/ */ +/* 276, /\* (56) *\/ */ +/* 280, /\* (69) *\/ */ +/* 284, /\* (71) *\/ */ +/* 288, /\* (70) *\/ */ +/* 292, /\* (62) *\/ */ +/* 296, /\* (39) *\/ */ +/* 300, /\* (54) *\/ */ +/* 304, /\* (43) *\/ */ +/* 308, /\* (54) *\/ */ +312, /* (30) */ +/* 316, /\* (8) *\/ */ +/* 320, /\* (5) *\/ */ +/* 324, /\* (7) *\/ */ +/* 328, /\* (14) *\/ */ +/* 332, /\* (13) *\/ */ +/* 336, /\* (8) *\/ */ +/* 340, /\* (7) *\/ */ +/* 344, /\* (6) *\/ */ +/* 348, /\* (2) *\/ */ +/* 352, /\* (7) *\/ */ +/* 356, /\* (18) *\/ */ +/* 360, /\* (5) *\/ */ +364, /* (12) */ +/* 368, /\* (2) *\/ */ +/* 372, /\* (4) *\/ */ +/* 376, /\* (2) *\/ */ +/* 380, /\* (5) *\/ */ +/* 384, /\* (1) *\/ */ +/* 392, /\* (4) *\/ */ +/* 396, /\* (3) *\/ */ +/* 404, /\* (4) *\/ */ +/* 408, /\* (2) *\/ */ +/* 412, /\* (3) *\/ */ +/* 416, /\* (2) *\/ */ +/* 420, /\* (3) *\/ */ +/* 424, /\* (2) *\/ */ +428, /* (16) */ +/* 432, /\* (4) *\/ */ +/* 436, /\* (1) *\/ */ +/* 440, /\* (3) *\/ */ +/* 452, /\* (1) *\/ */ +/* 456, /\* (2) *\/ */ +/* 460, /\* (8) *\/ */ +/* 468, /\* (1) *\/ */ +/* 472, /\* (2) *\/ */ +/* 484, /\* (1) *\/ */ +/* 492, /\* (4) *\/ */ +/* 500, /\* (1) *\/ */ +/* 504, /\* (2) *\/ */ +/* 508, /\* (1) *\/ */ +/* 516, /\* (2) *\/ */ +/* 524, /\* (5) *\/ */ +532, /* (15) */ +/* 536, /\* (3) *\/ */ +/* 540, /\* (1) *\/ */ +/* 556, /\* (4) *\/ */ +/* 576, /\* (3) *\/ */ +/* 588, /\* (8) *\/ */ +/* 612, /\* (1) *\/ */ +/* 616, /\* (1) *\/ */ +/* 620, /\* (5) *\/ */ +/* 648, /\* (1) *\/ */ +/* 652, /\* (1) *\/ */ +/* 680, /\* (1) *\/ */ +/* 704, /\* (1) *\/ */ +/* 716, /\* (1) *\/ */ +/* 772, /\* (1) *\/ */ +/* 776, /\* (1) *\/ */ +1032, /* (7549) */ +/* 1044, /\* (14) *\/ */ +2076, /* (14) */ +4116, /* (9) */ +8212, /* (6) */ +16404, /* (4) */ +63504, /* (7) */ +135636, /* (2) */ +253992, /* (7) */ +1050864, /* (1) */ +2097152 /* FIXME: FAIL HERE OR ABOVE */ +}; +#endif +#define FRAGSBITS (sizeof(fragsz)/sizeof(fragsz[0])) + +struct MPMAP { + struct MPMAP *next; + unsigned int size; + unsigned int usize; +}; + +struct MP { + unsigned int psize; + struct FRAG *avail[FRAGSBITS]; + struct MPMAP mpm; +}; struct FRAG { struct FRAG *next; @@ -83,17 +330,9 @@ static unsigned int to_bits(unsigned int size) { return i; /* NOTREACHED */ } static unsigned int from_bits(unsigned int bits) { + if (bits >= FRAGSBITS) return 0; return fragsz[bits]; } -/* static unsigned int to_bits(unsigned int size) { */ -/* unsigned int i; */ -/* for(i=0; i<32; i++) */ -/* if((unsigned int)1<= size) return i; */ -/* return i; /\* NOTREACHED *\/ */ -/* } */ -/* static unsigned int from_bits(unsigned int bits) { */ -/* return 1<mpm; /* check_all(mp); */ - if (!size) return NULL; - - j = sbits+2; - if (j<7) j = 7; - if (j > 32) j = 32; - - j=sbits; - - for (i=sbits; iavail[i])) break; + if (!size || sbits == FRAGSBITS) return NULL; /* Case 1: We have a free'd frag */ - if(f) { + if((f = mp->avail[sbits])) { spam("malloc %p size %u (freed)\n", f, roundup(size)); - mp->avail[i] = f->next; + mp->avail[sbits] = f->next; return &f->fake; } - needed = from_bits(sbits); + if (!(needed = from_bits(sbits))) return NULL; /* Case 2: We have nuff room available for this frag already */ while(mpm) { @@ -233,7 +463,8 @@ void *mp_realloc(struct MP *mp, void *ptr, size_t size) { if (!ptr) return mp_malloc(mp, size); spam("realloc @ %p (size %u -> %u))\n", f, from_bits(f->sbits), size); - csize = from_bits(f->sbits) - FRAG_OVERHEAD; + if(!(csize = from_bits(f->sbits))) return NULL; + csize -= FRAG_OVERHEAD; if (csize >= size) return ptr; if (!(new_ptr = mp_malloc(mp, size))) return NULL; @@ -249,7 +480,11 @@ void *mp_realloc2(struct MP *mp, void *ptr, size_t size) { if (!ptr) return mp_malloc(mp, size); spam("realloc @ %p (size %u -> %u))\n", f, from_bits(f->sbits), size); - csize = from_bits(f->sbits) - FRAG_OVERHEAD; + if(!(csize = from_bits(f->sbits))) { + mp_free(mp, ptr); + return NULL; + } + csize -= FRAG_OVERHEAD; if (csize >= size) return ptr; if ((new_ptr = mp_malloc(mp, size))) memcpy(new_ptr, ptr, csize); diff --git a/libclamav/mpool.h b/libclamav/mpool.h index 74c533aed..60d3c03d0 100644 --- a/libclamav/mpool.h +++ b/libclamav/mpool.h @@ -23,103 +23,6 @@ #ifdef USE_MPOOL -static const unsigned int fragsz[] = { -24, /* (33067) */ -32, /* (93876) */ -40, /* (731459) */ -48, /* (35286) */ -56, /* (6930) */ -64, /* (442013) */ -72, /* (2706) */ -80, /* (2252) */ -88, /* (3631) */ -96, /* (2594) */ -104, /* (3679) */ -112, /* (3697) */ -120, /* (3991) */ -128, /* (5141) */ -136, /* (22458) */ -144, /* (4320) */ -152, /* (4296) */ -160, /* (12177) */ -168, /* (18024) */ -/* 176, /\* (323) *\/ */ -/* 184, /\* (329) *\/ */ -/* 192, /\* (202) *\/ */ -/* 200, /\* (221) *\/ */ -/* 208, /\* (166) *\/ */ -/* 216, /\* (179) *\/ */ -/* 224, /\* (216) *\/ */ -/* 232, /\* (172) *\/ */ -/* 240, /\* (157) *\/ */ -/* 248, /\* (178) *\/ */ -256, /* (133) */ -/* 264, /\* (157) *\/ */ -/* 272, /\* (140) *\/ */ -/* 280, /\* (161) *\/ */ -/* 288, /\* (125) *\/ */ -/* 296, /\* (141) *\/ */ -/* 304, /\* (100) *\/ */ -/* 312, /\* (97) *\/ */ -/* 320, /\* (70) *\/ */ -/* 328, /\* (13) *\/ */ -/* 336, /\* (21) *\/ */ -/* 344, /\* (21) *\/ */ -/* 352, /\* (13) *\/ */ -/* 360, /\* (9) *\/ */ -/* 368, /\* (8) *\/ */ -/* 376, /\* (14) *\/ */ -/* 384, /\* (5) *\/ */ -/* 392, /\* (6) *\/ */ -/* 400, /\* (4) *\/ */ -/* 408, /\* (2) *\/ */ -/* 416, /\* (6) *\/ */ -/* 424, /\* (5) *\/ */ -/* 432, /\* (4) *\/ */ -/* 440, /\* (4) *\/ */ -/* 448, /\* (4) *\/ */ -/* 464, /\* (2) *\/ */ -/* 472, /\* (2) *\/ */ -/* 480, /\* (1) *\/ */ -/* 496, /\* (1) *\/ */ -/* 512, /\* (2) *\/ */ -520, /* (11) */ -/* 536, /\* (1) *\/ */ -/* 544, /\* (2) *\/ */ -/* 552, /\* (1) *\/ */ -/* 584, /\* (3) *\/ */ -/* 600, /\* (1) *\/ */ -/* 624, /\* (1) *\/ */ -/* 656, /\* (1) *\/ */ -/* 784, /\* (2) *\/ */ -1032, /* (11) */ -/* 2056, /\* (14) *\/ */ -2064, /* (7456) */ -4104, /* (14) */ -8200, /* (9) */ -16392, /* (6) */ -32776, /* (4) */ -63512, /* (7) */ -134408, /* (1) */ -507984, /* (7) */ -1051040, /* (1) */ -2097152 -}; - -#define FRAGSBITS (sizeof(fragsz)/sizeof(fragsz[0])) - -struct MPMAP { - struct MPMAP *next; - unsigned int size; - unsigned int usize; -}; - -struct MP { - unsigned int psize; - struct FRAG *avail[FRAGSBITS]; - struct MPMAP mpm; -}; - typedef struct MP mp_t; mp_t *mp_create(void); @@ -142,5 +45,3 @@ void mp_flush(mp_t *mp); #endif /* USE_MPOOL */ #endif - -