Blame gmodule/gmodule-dyld.c

Packit ae235b
/* GMODULE - GLIB wrapper code for dynamic module loading
Packit ae235b
 * Copyright (C) 1998, 2000 Tim Janik
Packit ae235b
 *
Packit ae235b
 * dyld (Darwin) GMODULE implementation
Packit ae235b
 * Copyright (C) 2001 Dan Winship
Packit ae235b
 *
Packit ae235b
 * This library is free software; you can redistribute it and/or
Packit ae235b
 * modify it under the terms of the GNU Lesser General Public
Packit ae235b
 * License as published by the Free Software Foundation; either
Packit ae235b
 * version 2.1 of the License, or (at your option) any later version.
Packit ae235b
 *
Packit ae235b
 * This library is distributed in the hope that it will be useful,
Packit ae235b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit ae235b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
Packit ae235b
 * Lesser General Public License for more details.
Packit ae235b
 *
Packit ae235b
 * You should have received a copy of the GNU Lesser General Public
Packit ae235b
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit ae235b
 */
Packit ae235b
#include "config.h"
Packit ae235b
Packit ae235b
#include <mach-o/dyld.h>
Packit ae235b
Packit ae235b
static gpointer self_module = GINT_TO_POINTER (1);
Packit ae235b
Packit ae235b
static gpointer
Packit ae235b
_g_module_open (const gchar *file_name,
Packit ae235b
		gboolean     bind_lazy,
Packit ae235b
		gboolean     bind_local)
Packit ae235b
{
Packit ae235b
  NSObjectFileImage image;
Packit ae235b
  NSObjectFileImageReturnCode ret;
Packit ae235b
  NSModule module;
Packit ae235b
  unsigned long options;
Packit ae235b
  char *msg;
Packit ae235b
Packit ae235b
  ret = NSCreateObjectFileImageFromFile (file_name, &image);
Packit ae235b
  if (ret != NSObjectFileImageSuccess)
Packit ae235b
    {
Packit ae235b
      switch (ret)
Packit ae235b
	{
Packit ae235b
	case NSObjectFileImageInappropriateFile:
Packit ae235b
	case NSObjectFileImageFormat:
Packit ae235b
	  msg = g_strdup_printf ("%s is not a loadable module", file_name);
Packit ae235b
	  break;
Packit ae235b
Packit ae235b
	case NSObjectFileImageArch:
Packit ae235b
	  msg = g_strdup_printf ("%s is not built for this architecture",
Packit ae235b
				 file_name);
Packit ae235b
	  break;
Packit ae235b
Packit ae235b
	case NSObjectFileImageAccess:
Packit ae235b
	  if (access (file_name, F_OK) == 0)
Packit ae235b
	    msg = g_strdup_printf ("%s: permission denied", file_name);
Packit ae235b
	  else
Packit ae235b
	    msg = g_strdup_printf ("%s: no such file or directory", file_name);
Packit ae235b
	  break;
Packit ae235b
Packit ae235b
	default:
Packit ae235b
	  msg = g_strdup_printf ("unknown error for %s", file_name);
Packit ae235b
	  break;
Packit ae235b
	}
Packit ae235b
Packit ae235b
      g_module_set_error (msg);
Packit ae235b
      g_free (msg);
Packit ae235b
      return NULL;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  options = NSLINKMODULE_OPTION_RETURN_ON_ERROR;
Packit ae235b
  if (bind_local)
Packit ae235b
    options |= NSLINKMODULE_OPTION_PRIVATE;
Packit ae235b
  if (!bind_lazy)
Packit ae235b
    options |= NSLINKMODULE_OPTION_BINDNOW;
Packit ae235b
  module = NSLinkModule (image, file_name, options);
Packit ae235b
  NSDestroyObjectFileImage (image);
Packit ae235b
  if (!module)
Packit ae235b
    {
Packit ae235b
      NSLinkEditErrors c;
Packit ae235b
      int error_number;
Packit ae235b
      const char *file, *error;
Packit ae235b
Packit ae235b
      NSLinkEditError (&c, &error_number, &file, &error);
Packit ae235b
      msg = g_strdup_printf ("could not link %s: %s", file_name, error);
Packit ae235b
      g_module_set_error (msg);
Packit ae235b
      g_free (msg);
Packit ae235b
      return NULL;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  return module;
Packit ae235b
}
Packit ae235b
Packit ae235b
static gpointer
Packit ae235b
_g_module_self (void)
Packit ae235b
{
Packit ae235b
  return &self_module;
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
_g_module_close (gpointer handle,
Packit ae235b
		 gboolean is_unref)
Packit ae235b
{
Packit ae235b
  if (handle == &self_module)
Packit ae235b
    return;
Packit ae235b
Packit ae235b
  if (!NSUnLinkModule (handle, 0))
Packit ae235b
    g_module_set_error ("could not unlink module");
Packit ae235b
}
Packit ae235b
Packit ae235b
static gpointer
Packit ae235b
_g_module_symbol (gpointer     handle,
Packit ae235b
		  const gchar *symbol_name)
Packit ae235b
{
Packit ae235b
  NSSymbol sym;
Packit ae235b
  char *msg;
Packit ae235b
Packit ae235b
  if (handle == &self_module)
Packit ae235b
    {
Packit ae235b
      if (NSIsSymbolNameDefined (symbol_name))
Packit ae235b
	sym = NSLookupAndBindSymbol (symbol_name);
Packit ae235b
      else
Packit ae235b
	sym = NULL;
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
    sym = NSLookupSymbolInModule (handle, symbol_name);
Packit ae235b
Packit ae235b
  if (!sym)
Packit ae235b
    {
Packit ae235b
      msg = g_strdup_printf ("no such symbol %s", symbol_name);
Packit ae235b
      g_module_set_error (msg);
Packit ae235b
      g_free (msg);
Packit ae235b
      return NULL;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  return NSAddressOfSymbol (sym);
Packit ae235b
}
Packit ae235b
Packit ae235b
static gchar*
Packit ae235b
_g_module_build_path (const gchar *directory,
Packit ae235b
		      const gchar *module_name)
Packit ae235b
{
Packit ae235b
  if (directory && *directory)
Packit ae235b
    {
Packit ae235b
      if (strncmp (module_name, "lib", 3) == 0)
Packit ae235b
	return g_strconcat (directory, "/", module_name, NULL);
Packit ae235b
      else
Packit ae235b
	return g_strconcat (directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL);
Packit ae235b
    }
Packit ae235b
  else if (strncmp (module_name, "lib", 3) == 0)
Packit ae235b
    return g_strdup (module_name);
Packit ae235b
  else
Packit ae235b
    return g_strconcat ("lib", module_name, "." G_MODULE_SUFFIX, NULL);
Packit ae235b
}