home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-src.tgz / tar.out / fsf / octave / src / dynamic-ld.cc < prev    next >
C/C++ Source or Header  |  1996-09-28  |  7KB  |  315 lines

  1. // dynamic-ld.cc                                         -*- C++ -*-
  2. /*
  3.  
  4. Copyright (C) 1993, 1994, 1995 John W. Eaton
  5.  
  6. This file is part of Octave.
  7.  
  8. Octave is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. Octave is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Octave; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. */
  23.  
  24. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27.  
  28. #include <strstream.h>
  29.  
  30. extern "C"
  31. {
  32. #ifdef WITH_DLD
  33. #include <dld/dld.h>
  34. #endif
  35.  
  36. #define boolean kpathsea_boolean
  37. #define false kpathsea_false
  38. #define true kpathsea_true
  39. #include <kpathsea/pathsearch.h>
  40. #undef true
  41. #undef false
  42. #undef boolean
  43. }
  44.  
  45. #include "dynamic-ld.h"
  46. #include "tree-const.h"
  47. #include "user-prefs.h"
  48. #include "variables.h"
  49. #include "defaults.h"
  50. #include "dirfns.h"
  51. #include "octave.h"
  52. #include "utils.h"
  53. #include "error.h"
  54.  
  55. typedef builtin_function * (*Octave_builtin_fcn_struct_fcn)(void);
  56.  
  57. // XXX FIXME XXX -- should this list be in a user-level variable,
  58. // with default taken from the environment?
  59.  
  60. #ifdef WITH_DLD
  61.  
  62. #ifndef STD_LIB_PATH
  63. #define STD_LIB_PATH "/lib:/usr/lib:/usr/local/lib"
  64. #endif
  65.  
  66. #ifndef OCTAVE_LIB_PATH
  67. #define OCTAVE_LIB_PATH OCTAVE_LIBDIR ":" FLIB_PATH ":" CXXLIB_PATH 
  68. #endif
  69.  
  70. static char *lib_dir_path = OCTAVE_LIB_PATH ":" STD_LIB_PATH;
  71.  
  72. // This is the list of interesting libraries that Octave is linked
  73. // with.  Maybe it should include the readline, info, and kpathsea
  74. // libraries.  Would there ever be a time that they would really be
  75. // needed?
  76.  
  77. #ifndef SYSTEM_LIB_LIST
  78. #define SYSTEM_LIB_LIST "libtermcap.a:libm.a" ":" CXXLIB_LIST
  79. #endif
  80.  
  81. #ifndef OCTAVE_LIB_LIST
  82. #define OCTAVE_LIB_LIST "liboctdld.a:liboctave.a:libcruft.a:libdld.a"
  83. #endif
  84.  
  85. static char *lib_list = OCTAVE_LIB_LIST ":" FLIB_LIST ":" SYSTEM_LIB_LIST;
  86.  
  87. static char *
  88. mangle_octave_builtin_name (const char *name)
  89. {
  90.   char *tmp = strconcat (name, "__FRC13Octave_objecti");
  91.   char *retval = strconcat ("F", tmp);
  92.   delete [] tmp;
  93.   return retval;
  94. }
  95.  
  96. static char *
  97. mangle_octave_oct_file_name (const char *name)
  98. {
  99.   char *tmp = strconcat (name, "__Fv");
  100.   char *retval = strconcat ("FS", tmp);
  101.   delete [] tmp;
  102.   return retval;
  103. }
  104.  
  105. static void
  106. octave_dld_init (void)
  107. {
  108.   static int initialized = 0;
  109.  
  110.   if (! initialized)
  111.     {
  112.       char *full_path = 0;
  113.  
  114.       char *tmp = dld_find_executable (raw_prog_name);
  115.       if (tmp)
  116.     {
  117.       full_path = make_absolute (tmp, the_current_working_directory);
  118.       free (tmp);
  119.     }
  120.  
  121.       if (full_path)
  122.     {
  123.       int status = dld_init (full_path);
  124.  
  125.       if (status != 0)
  126.         error ("failed to load symbols from `%s'", full_path);
  127.       else
  128.         initialized = 1;
  129.     }
  130.       else
  131.     {
  132.       error ("octave_dld_init: can't find full path to `%s'",
  133.          raw_prog_name);
  134.     }
  135.     }
  136. }
  137.  
  138. static void
  139. octave_list_undefined_symbols (ostream& os)
  140. {
  141.   char **list = dld_list_undefined_sym ();
  142.  
  143.   if (list)
  144.     {
  145.       os << "undefined symbols:\n\n";
  146.       for (int i = 0; i < dld_undefined_sym_count; i++)
  147.     os << list[i] << "\n";
  148.       os << "\n";
  149.     }
  150. }
  151.  
  152. static void *
  153. dld_octave_resolve_reference (const char *name, const char *file = 0)
  154. {
  155.   dld_create_reference (name);
  156.  
  157.   if (file)
  158.     {
  159.       if (dld_link (file) != 0)
  160.     {
  161.       error ("failed to link file %s", file);
  162.       return 0;
  163.     }
  164.  
  165.       if (dld_function_executable_p (name))
  166.     return (void *) dld_get_func (name);
  167.     }
  168.  
  169. // For each library, try to find it in a list of directories, then
  170. // link to it.  It would have been nice to use the kpathsea functions
  171. // here too, but calls to them can't be nested as they would need to
  172. // be here...
  173.  
  174.   char **libs = pathstring_to_vector (lib_list);
  175.   char **ptr = libs;
  176.   char *lib_list_elt;
  177.  
  178.   while ((lib_list_elt = *ptr++))
  179.     {
  180.       char *lib = kpse_path_search (lib_dir_path, lib_list_elt,
  181.                     kpathsea_true);
  182.  
  183.       if (lib && dld_link (lib) != 0)
  184.     {
  185.       error ("failed to link library %s", lib);
  186.       return 0;
  187.     }
  188.  
  189.       if (dld_function_executable_p (name))
  190.     return (void *) dld_get_func (name);
  191.     }
  192.  
  193. // If we get here, there was a problem.
  194.  
  195.   ostrstream output_buf;
  196.   octave_list_undefined_symbols (output_buf);
  197.   char *msg = output_buf.str ();
  198.   error (msg);
  199.   delete [] msg;
  200.  
  201.   return 0;
  202. }
  203.  
  204. static Octave_builtin_fcn
  205. dld_octave_builtin (const char *name)
  206. {
  207.   Octave_builtin_fcn retval = 0;
  208.  
  209.   char *mangled_name = mangle_octave_builtin_name (name);
  210.  
  211.   retval = (Octave_builtin_fcn) dld_octave_resolve_reference (mangled_name);
  212.  
  213.   delete [] mangled_name;
  214.  
  215.   return retval;
  216. }
  217.  
  218. static int
  219. dld_octave_oct_file (const char *name)
  220. {
  221.   char *oct_file = oct_file_in_path (name);
  222.  
  223.   if (oct_file)
  224.     {
  225.       char *mangled_name = mangle_octave_oct_file_name (name);
  226.  
  227.       Octave_builtin_fcn_struct_fcn f =
  228.     (Octave_builtin_fcn_struct_fcn) dld_octave_resolve_reference
  229.       (mangled_name, oct_file);
  230.  
  231.       if (f)
  232.     {
  233.       builtin_function *s = f ();
  234.  
  235.       if (s)
  236.         {
  237.           install_builtin_function (s);
  238.           return 1;
  239.         }
  240.     }
  241.  
  242.       delete [] oct_file;
  243.     }
  244.  
  245.   return 0;
  246. }
  247.  
  248. #endif
  249.  
  250. Octave_builtin_fcn
  251. load_octave_builtin (const char *name)
  252. {
  253. #ifdef WITH_DLD
  254.   return dld_octave_builtin (name);
  255. #else
  256.   return 0;
  257. #endif
  258. }
  259.  
  260. int
  261. load_octave_oct_file (const char *name)
  262. {
  263. #ifdef WITH_DLD
  264.   return dld_octave_oct_file (name);
  265. #endif
  266.   return 0;
  267. }
  268.  
  269. void
  270. init_dynamic_linker (void)
  271. {
  272. #ifdef WITH_DLD
  273.   octave_dld_init ();
  274. #endif
  275. }
  276.  
  277. // OLD:
  278.  
  279. #if 0
  280.  
  281. void
  282. octave_dld_tc2_unlink_by_symbol (const char *name, int hard)
  283. {
  284. // XXX FIXME XXX -- need to determine the name mangling scheme
  285. // automatically, in case it changes, or is different on different
  286. // systems, even if they have g++.
  287.  
  288.   char *mangled_fcn_name = strconcat (name, "__FRC13Octave_objecti");
  289.  
  290.   int status = dld_unlink_by_symbol (mangled_fcn_name, hard);
  291.  
  292.   if (status != 0)
  293.     error ("octave_dld_tc2_unlink_by_symbol: %s", dld_strerror (0));
  294.  
  295.   delete [] mangled_fcn_name;
  296. }
  297.  
  298. void
  299. octave_dld_tc2_unlink_by_file (const char *name, int hard)
  300. {
  301.   int status = dld_unlink_by_file (name, hard);
  302.  
  303.   if (status != 0)
  304.     error ("octave_dld_tc2_unlink_by_file: %s", dld_strerror (0));
  305. }
  306.  
  307. #endif
  308.  
  309. /*
  310. ;;; Local Variables: ***
  311. ;;; mode: C++ ***
  312. ;;; page-delimiter: "^/\\*" ***
  313. ;;; End: ***
  314. */
  315.