summaryrefslogtreecommitdiffstats
path: root/src/objsearch.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@shell.devel.redhat.com>2009-09-04 02:29:08 -0400
committerJiri Olsa <jolsa@shell.devel.redhat.com>2009-09-04 02:29:08 -0400
commit04f3fbbfdb3a5dd197dbc25ca18ad244f1fbf6a5 (patch)
tree8e53039a4f5d1a4571000bc06214053261aebf8d /src/objsearch.c
downloadlatrace-04f3fbbfdb3a5dd197dbc25ca18ad244f1fbf6a5.tar.gz
latrace-04f3fbbfdb3a5dd197dbc25ca18ad244f1fbf6a5.tar.xz
latrace-04f3fbbfdb3a5dd197dbc25ca18ad244f1fbf6a5.zip
initial commit - 0.5.7
Diffstat (limited to 'src/objsearch.c')
-rw-r--r--src/objsearch.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/src/objsearch.c b/src/objsearch.c
new file mode 100644
index 0000000..ae0823f
--- /dev/null
+++ b/src/objsearch.c
@@ -0,0 +1,192 @@
+/*
+ Copyright (C) 2008, 2009 Jiri Olsa <olsajiri@gmail.com>
+
+ This file is part of the latrace.
+
+ The latrace is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The latrace 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 the latrace (file COPYING). If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <string.h>
+
+#include "config.h"
+
+
+static int add_subst(struct lt_config_audit *cfg, char *subst)
+{
+ struct lt_objsearch *s;
+ char *dst, *src = subst;
+ int type;
+
+ if (cfg->subst_cnt == LT_NAMES_MAX)
+ return -1;
+
+ do {
+ if ((dst = strchr(subst, '='))) {
+ type = LT_OS_PATH;
+ break;
+ }
+
+ if ((dst = strchr(subst, '%'))) {
+ type = LT_OS_PTN;
+ break;
+ }
+
+ if ((dst = strchr(subst, '~'))) {
+ type = LT_OS_PTN2PATH;
+ break;
+ }
+
+ } while(0);
+
+ if (!dst)
+ return -1;
+
+ *dst++ = 0x0;
+
+ PRINT_VERBOSE(cfg->sh.verbose, 2, "adding subst type %d, src [%s], dst [%s]\n",
+ type, src, dst);
+
+ s = &cfg->subst[cfg->subst_cnt++];
+ s->type = type;
+ s->src = src;
+ s->dst = dst;
+
+ return 0;
+}
+
+/*
+ Comparing src with the name, if matched
+ replace the name with dst.
+
+ name -> /lib/krava.so
+ src -> /lib/krava.so
+ dst -> /lib/debil.so
+
+ ret -> /lib/debil.so
+*/
+static int match_path(struct lt_config_audit *cfg, const char *name,
+ struct lt_objsearch *s, char **ret)
+{
+ PRINT_VERBOSE(cfg->sh.verbose, 2, "name [%s], src [%s], dst [%s]\n",
+ name, s->src, s->dst);
+
+ *ret = s->dst;
+
+ if (!strcmp(name, s->src))
+ return 1;
+
+ return 0;
+}
+
+/*
+ Matching src in the name, if found,
+ replace the src with dst part.
+
+ name -> /lib/krava.so
+ src -> krava
+ dst -> debil
+
+ ret -> /lib/debil.so
+*/
+static int match_ptn(struct lt_config_audit *cfg, const char *name,
+ struct lt_objsearch *s, char **ret)
+{
+ char *pat, *r;
+
+ PRINT_VERBOSE(cfg->sh.verbose, 2, "name [%s], src [%s], dst [%s]\n",
+ name, s->src, s->dst);
+
+ pat = strstr(name, s->src);
+ if (!pat)
+ return 0;
+
+ r = *ret = malloc(strlen(name) + strlen(s->dst));
+ if (!r) {
+ perror("malloc failed");
+ return 0;
+ }
+
+ strncpy(r, name, pat - name);
+ r += (pat - name);
+ strcpy(r, s->dst);
+ strcat(r, pat + strlen(s->src));
+
+ PRINT_VERBOSE(cfg->sh.verbose, 2, "return %s\n", *ret);
+
+ return 1;
+}
+
+/*
+ Looking for src in the name, if found,
+ replace the name with dst.
+
+ name -> /lib/krava.so
+ src -> krava
+ dst -> /lib/krava1.so
+
+ ret -> /lib/krava1.so
+*/
+static int match_ptn2path(struct lt_config_audit *cfg, const char *name,
+ struct lt_objsearch *s, char **ret)
+{
+ PRINT_VERBOSE(cfg->sh.verbose, 2, "name [%s], src [%s], dst [%s]\n",
+ name, s->src, s->dst);
+
+ *ret = s->dst;
+ if (strstr(name, s->src))
+ return 1;
+
+ return 0;
+}
+
+static int match(struct lt_config_audit *cfg, const char *name,
+ struct lt_objsearch *s, char **ret)
+{
+ switch(s->type) {
+ case LT_OS_PATH:
+ return match_path(cfg, name, s, ret);
+ case LT_OS_PTN:
+ return match_ptn(cfg, name, s, ret);
+ case LT_OS_PTN2PATH:
+ return match_ptn2path(cfg, name, s, ret);
+ };
+
+ return 0;
+}
+
+int lt_objsearch_init(struct lt_config_audit *cfg, char **ptr, int cnt)
+{
+ int i;
+
+ for(i = 0; i < cnt; i++)
+ if (-1 == add_subst(cfg, ptr[i]))
+ return -1;
+
+ return 0;
+}
+
+char* lt_objsearch(struct lt_config_audit *cfg, const char *name,
+ uintptr_t *cookie, unsigned int flag)
+{
+ int i;
+ char *ret = NULL;
+
+ for(i = 0; i < cfg->subst_cnt; i++)
+ if (match(cfg, name, &cfg->subst[i], &ret))
+ return ret;
+
+ return (char*) name;
+}