Updates, bug fixes for using the dynamic linker to look up paths of

object files from which classes have been loaded


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14872 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Nicola Pero 2002-10-30 02:27:45 +00:00
parent 8b3989d562
commit 54818427e8
5 changed files with 151 additions and 85 deletions

View file

@ -1,3 +1,20 @@
Wed Oct 30 03:14:34 2002 Nicola Pero <n.pero@mi.flashnet.it>
* Headers/gnustep/base/objc-load.h: Added copyright notice.
(objc_get_symbol_path): Declare to take a Category *, not a struct
objc_category *, argument; documented.
* Source/objc-load.m: Include config.h first. Define _GNU_SOURCE
if HAVE_DLADDR is defined.
(objc_get_symbol_path): Fixed crash with classes or categories
with long names. Updated declaration.
* config/objc-sys-dynamic.m4 (OBJC_SYS_DYNAMIC_LINKER): Print a
message displaying the type of dynamic linker found. Add -ldl on
the link line for linux-gnu and other systems, so that dladdr() is
actually found. With the 'simple' linker, print a message saying
if we found dladdr() or not.
(OBJC_SYS_DYNAMIC): Historical unused macro removed.
* configure: Regenerated.
2002-10-28 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSFileManager.m: include statvfs.h if available.

View file

@ -1,9 +1,30 @@
/*
objc-load.h - Dynamically load in Obj-C modules (Classes, Categories)
/*
objc-load.h - Dynamically load in Obj-C modules (Classes, Categories)
Copyright (C) 1993, 2002 Free Software Foundation, Inc.
Copyright (C) 1993, Adam Fedor.
*/
Author: Adam Fedor
Date: 1993
This file is part of the GNUstep Objective-C Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
If you are interested in a warranty or support for this source code,
contact Scott Christley <scottc@net-community.com> for more information.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __objc_load_h_INCLUDE
#define __objc_load_h_INCLUDE
@ -40,8 +61,51 @@ extern long objc_unload_modules(
FILE *errorStream,
void (*unloadCallback)(Class, struct objc_category *));
extern NSString *objc_get_symbol_path(
Class theClass,
struct objc_category *theCategory);
/*
* objc_get_symbol_path() returns the path to the object file from
* which a certain class was loaded.
*
* If the class was loaded from a shared library, this returns the
* filesystem path to the shared library; if it was loaded from a
* dynamical object (such as a bundle or framework dynamically
* loaded), it returns the filesystem path to the object file; if the
* class was loaded from the main executable, it returns the
* filesystem path to the main executable path.
*
* This function is implemented by using the available features of
* the dynamic linker on the specific platform we are running on.
*
* On some platforms, the dynamic linker does not provide enough
* facilities to support the objc_get_symbol_path() function at all;
* in this case, objc_get_symbol_path() always returns nil.
*
* On my platform (a Debian GNU Linux), it seems the dynamic linker
* always returns the filesystem path that was used to load the
* module. So it returns the full filesystem path for shared libraries
* and bundles (which is very nice), but unfortunately it returns
* argv[0] (which might be something as horrible as './obj/test')
* for classes in the main executable.
*
* If theCategory argument is not NULL, objc_get_symbol_path() will return
* the filesystem path to the module from which the category theCategory
* of the class theClass was loaded.
*
* Currently, the function will return nil if any of the following
* conditions is satisfied:
* - the required functionality is not available on the platform we are
* running on;
* - memory allocation fails;
* - the symbol for that class/category could not be found.
*
* In general, if the function returns nil, it means something serious
* went wrong in the system preventing it from getting the symbol path.
* If your code is to be portable, you (unfortunately) have to be prepared
* to work around it in some way when this happens.
*
* It seems that this function has no corresponding function in the NeXT
* runtime ... as far as I know.
*/
extern
NSString *objc_get_symbol_path (Class theClass, Category *theCategory);
#endif /* __objc_load_h_INCLUDE */

View file

@ -29,15 +29,23 @@
*/
#include <config.h>
#ifdef HAVE_DLADDR
/* Define _GNU_SOURCE because that is required with GNU libc in order
* to have dladdr() available. */
# define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <objc/objc-api.h>
#ifndef NeXT_RUNTIME
#include <objc/objc-list.h>
# include <objc/objc-list.h>
#else
#include <objc/objc-load.h>
# include <objc/objc-load.h>
#endif
#include <config.h>
#include <Foundation/objc-load.h>
#include <Foundation/NSString.h>
#include <Foundation/NSDebug.h>
@ -63,7 +71,7 @@ objc_get_uninstalled_dtable()
#endif /* ! NeXT */
/* Declaration from NSBundle.m */
const char *objc_executable_location( void );
const char *objc_executable_location (void);
/* dynamic_loaded is YES if the dynamic loader was sucessfully initialized. */
static BOOL dynamic_loaded;
@ -313,28 +321,28 @@ objc_unload_modules(FILE *errorStream,
}
NSString *
objc_get_symbol_path(Class theClass, struct objc_category *theCategory)
objc_get_symbol_path(Class theClass, Category *theCategory)
{
const char *ret;
char buf[125], *p = buf;
int len = strlen(theClass->name);
if (!theCategory)
if (theCategory == NULL)
{
if (len+sizeof(char)*19 > sizeof(buf))
if (len + sizeof(char)*19 > sizeof(buf))
{
p = malloc(len+sizeof(char)*19);
p = malloc(len + sizeof(char)*19);
if (!p)
if (p == NULL)
{
fprintf(stderr, "Unable to allocate memory !!");
return nil;
}
}
memcpy(buf, "__objc_class_name_", sizeof(char)*18);
memcpy(&buf[18*sizeof(char)], theClass->name,
strlen(theClass->name)+1);
memcpy(p, "__objc_class_name_", sizeof(char)*18);
memcpy(&p[18*sizeof(char)], theClass->name,
strlen(theClass->name) + 1);
}
else
{
@ -344,19 +352,19 @@ objc_get_symbol_path(Class theClass, struct objc_category *theCategory)
{
p = malloc(len + sizeof(char)*23);
if (!p)
if (p == NULL)
{
fprintf(stderr, "Unable to allocate memory !!");
return nil;
}
}
memcpy(buf, "__objc_category_name_", sizeof(char)*21);
memcpy(&buf[21*sizeof(char)], theCategory->class_name,
strlen(theCategory->class_name)+1);
memcpy(&buf[strlen(p)], "_", 2*sizeof(char));
memcpy(&buf[strlen(p)], theCategory->category_name,
strlen(theCategory->category_name)+1);
memcpy(p, "__objc_category_name_", sizeof(char)*21);
memcpy(&p[21*sizeof(char)], theCategory->class_name,
strlen(theCategory->class_name) + 1);
memcpy(&p[strlen(p)], "_", 2*sizeof(char));
memcpy(&p[strlen(p)], theCategory->category_name,
strlen(theCategory->category_name) + 1);
}
ret = __objc_dynamic_get_symbol_path(0, p);
@ -368,7 +376,7 @@ objc_get_symbol_path(Class theClass, struct objc_category *theCategory)
if (ret)
{
return [NSString stringWithCString:ret];
return [NSString stringWithCString: ret];
}
return nil;

View file

@ -20,66 +20,25 @@ if test $DYNAMIC_LINKER = null; then
AC_CHECK_HEADER(dld/defs.h, DYNAMIC_LINKER=dld)
fi
# NB: This is used as follows: in Source/Makefile.postamble we copy
# $(DYNAMIC_LINKER)-load.h into dynamic-load.h
AC_MSG_CHECKING([for dynamic linker type])
AC_MSG_RESULT([$DYNAMIC_LINKER])
if test $DYNAMIC_LINKER = simple; then
AC_MSG_CHECKING([checking if dladdr() is available])
old_LDFLAGS="$LDFLAGS"
case "$target_os" in
linux-gnu*) LDFLAGS="$old_LDFLAGS -ldl";;
solaris*) LDFLAGS="$old_LDFLAGS -ldl";;
sysv4.2*) LDFLAGS="$old_LDFLAGS -ldl";;
esac
AC_TRY_LINK([#include <dlfcn.h>], dladdr(0,0);,
AC_DEFINE(HAVE_DLADDR,1, [Define if you have dladdr]))
AC_DEFINE(HAVE_DLADDR,1, [Define if you have dladdr])
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no]))
LDFLAGS="$old_LDFLAGS"
fi
AC_SUBST(DYNAMIC_LINKER)dnl
])
AC_DEFUN(OBJC_SYS_DYNAMIC_FLAGS,
[dnl
AC_REQUIRE([OBJC_CON_AUTOLOAD])dnl
AC_REQUIRE([OBJC_SYS_DYNAMIC_LINKER])dnl
#--------------------------------------------------------------------
# Set the flags for compiling dynamically loadable objects
#
# Makes the following substitutions:
# DYNAMIC_BUNDLER_LINKER - The command to link the object files into
# a dynamically loadable module.
# DYNAMIC_LDFLAGS - Flags required when compiling the main program
# that will do the dynamic linking
# DYNAMIC_CFLAGS - Flags required when compiling the object files that
# will be included in the loaded module.
#--------------------------------------------------------------------
if test $DYNAMIC_LINKER = dld; then
DYNAMIC_BUNDLER_LINKER="ld -r"
DYNAMIC_LDFLAGS="-static"
DYNAMIC_CFLAGS=""
elif test $DYNAMIC_LINKER = simple; then
save_LDFLAGS=$LDFLAGS
LDFLAGS="-shared"
AC_TRY_LINK([extern void loadf();], loadf();,
objc_shared_linker=yes, objc_shared_linker=no)
LDFLAGS=$save_LDFLAGS
if test $objc_shared_linker = yes; then
DYNAMIC_BUNDLER_LINKER='$(CC) -shared'
elif test $objc_cv_con_autoload = yes; then
DYNAMIC_BUNDLER_LINKER='$(CC) -Xlinker -r'
else
DYNAMIC_BUNDLER_LINKER='$(CC) -nostdlib'
fi
save_LDFLAGS=$LDFLAGS
LDFLAGS="-rdynamic"
AC_TRY_RUN([], objc_dynamic_ldflag="-rdynamic", objc_dynamic_ldflag="",
objc_dynamic_ldflag="")
LDFLAGS=$save_LDFLAGS
DYNAMIC_LDFLAGS="$objc_dynamic_ldflag"
DYNAMIC_CFLAGS="-fPIC"
elif test $DYNAMIC_LINKER = hpux; then
DYNAMIC_BUNDLER_LINKER='$(CC) -nostdlib -Xlinker -b'
DYNAMIC_LDFLAGS="-Xlinker -E"
DYNAMIC_CFLAGS="-fPIC"
elif test $DYNAMIC_LINKER = null; then
DYNAMIC_BUNDLER_LINKER='$(CC) -nostdlib -Xlinker -r'
DYNAMIC_LDFLAGS=""
DYNAMIC_CFLAGS=""
else
DYNAMIC_BUNDLER_LINKER='$(CC) -nostdlib -Xlinker -r'
DYNAMIC_LDFLAGS=""
DYNAMIC_CFLAGS=""
fi
AC_SUBST(DYNAMIC_BUNDLER_LINKER)dnl
AC_SUBST(DYNAMIC_LDFLAGS)dnl
AC_SUBST(DYNAMIC_CFLAGS)dnl
])

18
configure vendored
View file

@ -6316,7 +6316,20 @@ fi
fi
echo "$as_me:$LINENO: checking for dynamic linker type" >&5
echo $ECHO_N "checking for dynamic linker type... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $DYNAMIC_LINKER" >&5
echo "${ECHO_T}$DYNAMIC_LINKER" >&6
if test $DYNAMIC_LINKER = simple; then
echo "$as_me:$LINENO: checking checking if dladdr() is available" >&5
echo $ECHO_N "checking checking if dladdr() is available... $ECHO_C" >&6
old_LDFLAGS="$LDFLAGS"
case "$target_os" in
linux-gnu*) LDFLAGS="$old_LDFLAGS -ldl";;
solaris*) LDFLAGS="$old_LDFLAGS -ldl";;
sysv4.2*) LDFLAGS="$old_LDFLAGS -ldl";;
esac
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
@ -6352,11 +6365,16 @@ cat >>confdefs.h <<\_ACEOF
#define HAVE_DLADDR 1
_ACEOF
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LDFLAGS="$old_LDFLAGS"
fi