From bc19274a0b7af34b77c9328bba13d98f9f1e5315 Mon Sep 17 00:00:00 2001
From: Fons Rademakers <Fons.Rademakers@cern.ch>
Date: Thu, 11 Dec 2003 16:34:29 +0000
Subject: [PATCH] add rlibmap a utility used to build a map between classes and
 libraries. The rlibmap utility will create a system.rootlibmap file used to
 load the library for an unknown class. To be enabled in the very near future.

git-svn-id: http://root.cern.ch/svn/root/trunk@7733 27541ba8-7e3a-0410-8455-c3a389f83636
---
 Makefile              |   2 +-
 utils/Module.mk       |  16 +++-
 utils/src/rlibmap.cxx | 181 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+), 4 deletions(-)
 create mode 100644 utils/src/rlibmap.cxx

diff --git a/Makefile b/Makefile
index dd004f46f49..b69a6c4de07 100644
--- a/Makefile
+++ b/Makefile
@@ -309,7 +309,7 @@ endif
 include build/dummy.d          # must be last include
 endif
 
-rootcint:       all-cint $(ROOTCINTTMP) $(ROOTCINT)
+rootcint:       all-cint all-utils
 
 rootlibs:       rootcint compiledata $(ALLLIBS)
 
diff --git a/utils/Module.mk b/utils/Module.mk
index 57591fab600..7199768c329 100644
--- a/utils/Module.mk
+++ b/utils/Module.mk
@@ -19,8 +19,14 @@ ROOTCINTTMPO := $(ROOTCINTS:.cxx=_tmp.o)
 ROOTCINTTMP  := $(MODDIRS)/rootcint_tmp$(EXEEXT)
 ROOTCINT     := bin/rootcint$(EXEEXT)
 
+##### rlibmap #####
+RLIBMAPS     := $(MODDIRS)/rlibmap.cxx
+RLIBMAPO     := $(RLIBMAPS:.cxx=.o)
+RLIBMAPDEP   := $(RLIBMAPO:.o=.d)
+RLIBMAP      := bin/rlibmap$(EXEEXT)
+
 # include all dependency files
-INCLUDEFILES += $(ROOTCINTDEP)
+INCLUDEFILES += $(ROOTCINTDEP) $(RLIBMAPDEP)
 
 ##### local rules #####
 $(ROOTCINT):    $(CINTLIB) $(ROOTCINTO) $(MAKEINFO) $(IOSENUM)
@@ -33,15 +39,19 @@ $(ROOTCINTTMP): $(CINTTMPO) $(ROOTCINTS) $(MAKEINFO) $(IOSENUM)
 		$(LD) $(LDFLAGS) -o $@ \
 			$(ROOTCINTTMPO) $(CINTTMPO) $(CILIBS)
 
-all-utils:      $(ROOTCINTTMP) $(ROOTCINT)
+$(RLIBMAP):     $(RLIBMAPO)
+		$(LD) $(LDFLAGS) -o $@ $<
+
+all-utils:      $(ROOTCINTTMP) $(ROOTCINT) $(RLIBMAP)
 
 clean-utils:
-		@rm -f $(ROOTCINTTMPO) $(ROOTCINTO)
+		@rm -f $(ROOTCINTTMPO) $(ROOTCINTO) $(RLIBMAPO)
 
 clean::         clean-utils
 
 distclean-utils: clean-utils
 		@rm -f $(ROOTCINTDEP) $(ROOTCINTTMP) $(ROOTCINT) \
+		   $(RLIBMAPDEP) $(RLIBMAP) \
 		   $(UTILSDIRS)/*.exp $(UTILSDIRS)/*.lib
 
 distclean::     distclean-utils
diff --git a/utils/src/rlibmap.cxx b/utils/src/rlibmap.cxx
new file mode 100644
index 00000000000..831718e0274
--- /dev/null
+++ b/utils/src/rlibmap.cxx
@@ -0,0 +1,181 @@
+// @(#)root/utils:$Name:$:$Id:
+// Author: Fons Rademakers   05/12/2003
+
+/*************************************************************************
+ * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+// This program generates a map between class name and shared library.
+// Its output is in TEnv format.
+// Usage: rlibmap [-f] [-o <libmapfile>] <sofile> <sofile> ...
+// -f: output full library path name (not needed when ROOT library
+//     search path is used)
+// -o: output to write to specified file, otherwise to stdout
+
+
+#include <stdio.h>
+#include <string>
+#include <map>
+
+const char *usage = "Usage: %s [-f] [-o <libmapfile>] <sofile> <sofile> ...\n";
+
+#ifdef __linux
+#if defined(__INTEL_COMPILER) || (__GNUC__ >= 3)
+const char *kNM = "nm --demangle=gnu-v3";
+#else
+const char *kNM = "nm -C";
+#endif
+const char  kDefined = 'T';
+#endif
+
+#ifdef __sun
+const char *kNM = "nm -C -p";
+const char  kDefined = 'T';
+#endif
+
+#ifdef __alpha
+const char *kNM = "nm -B";
+const char  kDefined = 'T';
+#endif
+
+#ifdef __hpux
+namespace std { }
+const char *kNM = "nm++ -p";
+const char  kDefined = 'T';
+#endif
+
+#ifdef __APPLE__
+const char *kNM = "nm";
+const char  kDefined = 'T';
+#endif
+
+#ifdef __sgi
+const char *kNM = "nm -C";
+const char  kDefined = 'T';
+#endif
+
+using namespace std;
+
+
+int libmap(const char *lib, int fullpath, FILE *fp)
+{
+   char *nm = new char [strlen(lib)+50];
+
+#if defined(__APPLE__)
+   sprintf(nm, "%s %s | c++filt", kNM, lib);
+#else
+   sprintf(nm, "%s %s", kNM, lib);
+#endif
+
+   FILE *pf;
+   if ((pf = ::popen(nm, "r")) == 0) {
+      fprintf(stderr, "cannot execute: %s\n", nm);
+      return 1;
+   }
+
+   map<string,bool> unique;
+   char line[4096];
+   while ((fgets(line, 4096, pf)) != 0) {
+      //printf("line: %s", line);
+      unsigned long addr;
+      char type[5], symbol[4096];
+      addr = 0;
+      if (line[0] == '0') {
+          sscanf(line, "%lx %s %s", &addr, type, symbol);
+          //printf("addr = %.8lx, type = %s, symbol = %s\n", addr, type, symbol);
+      } else {
+          sscanf(line, "%s %s", type, symbol);
+          //printf("              type = %s, symbol = %s\n", type, symbol);
+      }
+
+      if (type[0] == kDefined) {
+         char *r;
+         if ((r = strrchr(symbol, ':'))) {
+            r--;
+            if (r && *r == ':') {
+               *r = 0;
+               string cls = symbol;
+               r += 2;
+               char *s;
+               if ((s = strchr(r, '[')) || (s = strchr(r, '('))) {
+                  *s = 0;
+                  string meth = r;
+                  if (cls == meth) {
+                     //printf("class %s in library %s\n", cls.c_str(), lib);
+                     unique[cls] = true;
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   ::pclose(pf);
+
+   const char *libbase = strrchr(lib, '/');
+   if (libbase && !fullpath)
+      libbase++;
+   else
+      libbase = lib;
+
+   map<string,bool>::const_iterator it;
+   for (it = unique.begin(); it != unique.end(); it++) {
+      fprintf(fp, "Library.%-35s %s\n", ((*it).first+":").c_str(), libbase);
+   }
+
+   delete [] nm;
+
+   return 0;
+}
+
+int main(int argc, char **argv)
+{
+   char **libs  = 0;
+   int fullpath = 0;
+   FILE *fp     = stdout;
+
+   if (argc > 1) {
+      int ic = 1;
+      if (!strcmp(argv[ic], "-f")) {
+         fullpath = 1;
+         ic++;
+      }
+      if (!strcmp(argv[ic], "-o")) {
+         ic++;
+         fp = fopen(argv[ic], "w");
+         if (!fp) {
+            fprintf(stderr, "cannot open output file %s\n", argv[ic]);
+            return 1;
+         }
+         ic++;
+      }
+      if (!strcmp(argv[ic], "-?") || !strcmp(argv[ic], "-h")) {
+         fprintf(stderr, usage, argv[0]);
+         return 1;
+      }
+      int args = argc - ic + 2;
+      libs = new char* [args];
+      libs[args-1] = 0;
+      for (int i = ic, j = 0; i < argc; i++, j++) {
+         libs[j] = argv[i];
+      }
+   } else {
+      fprintf(stderr, usage, argv[0]);
+      return 1;
+   }
+
+   int i = 0;
+   while (libs[i]) {
+      libmap(libs[i], fullpath, fp);
+      i++;
+   }
+
+   if (fp != stdout)
+      fclose(fp);
+
+   return 0;
+}
-- 
GitLab