mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
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:
parent
8b3989d562
commit
54818427e8
5 changed files with 151 additions and 85 deletions
17
ChangeLog
17
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
18
configure
vendored
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue