1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

- Added dlclose(), dlerror(), dlopen() and dlsym() functions, which are

available only under OS4. There is a variant of dlopen() in libunix.a
  which will perform a path name conversion. Note that these functions
  will not work in the thread-safe variant of the library because it
  would be unwise to tinker with the currently running program's binary.


git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@15207 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
Olaf Barthel
2010-08-21 11:37:03 +00:00
parent 1bdfc0d143
commit f600c5e37a
10 changed files with 232 additions and 299 deletions

View File

@ -1,10 +1,8 @@
- Added dlclose(), dlerror(), dlopen() and dlsym() functions, which are - Added dlclose(), dlerror(), dlopen() and dlsym() functions, which are
available only under OS4. There is a variant of dlopen() in libunix.a available only under OS4. There is a variant of dlopen() in libunix.a
which will perform a path name conversion. which will perform a path name conversion. Note that these functions
will not work in the thread-safe variant of the library because it
- The shared object initialization has to be performed before any local would be unwise to tinker with the currently running program's binary.
constructors are invoked, and after all local destructors have been
invoked.
- Added support for ELF shared objects and libraries. This is implemented through - Added support for ELF shared objects and libraries. This is implemented through
constructor/destructor functions, which means that you can use this constructor/destructor functions, which means that you can use this

View File

@ -1,5 +1,5 @@
/* /*
* $Id: crtbegin.c,v 1.12 2010-08-21 09:57:50 obarthel Exp $ * $Id: crtbegin.c,v 1.13 2010-08-21 11:37:03 obarthel Exp $
* *
* :ts=4 * :ts=4
* *
@ -10,16 +10,9 @@
/****************************************************************************/ /****************************************************************************/
#ifndef _STDLIB_HEADERS_H #ifndef EXEC_TYPES_H
#include "stdlib_headers.h" #include <exec/types.h>
#endif /* _STDLIB_HEADERS_H */ #endif /* EXEC_TYPES_H */
/****************************************************************************/
#include <libraries/elf.h>
#include <proto/elf.h>
#include <proto/dos.h>
/****************************************************************************/ /****************************************************************************/
@ -39,110 +32,10 @@ void _fini(void);
/****************************************************************************/ /****************************************************************************/
/* These are used to initialize the shared objects linked to this binary,
and for the dlopen(), dlclose() and dlsym() functions. */
struct Library * __ElfBase;
struct ElfIFace * __IElf;
Elf32_Handle __elf_handle;
/****************************************************************************/
static VOID close_elf_library(void)
{
if(__IElf != NULL)
{
DropInterface((struct Interface *)__IElf);
__IElf = NULL;
}
if(__ElfBase != NULL)
{
CloseLibrary(__ElfBase);
__ElfBase = NULL;
}
}
/****************************************************************************/
static BOOL open_elf_library(void)
{
BOOL success = FALSE;
/* We need elf.library V52.2 or higher. */
__ElfBase = OpenLibrary("elf.library",0);
if(__ElfBase == NULL || (__ElfBase->lib_Version < 52) || (__ElfBase->lib_Version == 52 && __ElfBase->lib_Revision < 2))
goto out;
__IElf = (struct ElfIFace *)GetInterface(__ElfBase,"main",1,NULL);
if(__IElf == NULL)
goto out;
success = TRUE;
out:
return(success);
}
/****************************************************************************/
static void shared_obj_exit(void)
{
/* If we got what we wanted, trigger the destructors,
etc. in the shared objects linked to this binary. */
if(__elf_handle != NULL)
InitSHLibs(__elf_handle,FALSE);
close_elf_library();
}
/****************************************************************************/
static void shared_obj_init(void)
{
struct ElfIFace * IElf;
BOOL success = FALSE;
BPTR segment_list;
if(!open_elf_library())
goto out;
/* Try to find the Elf handle associated with this
program's segment list. */
segment_list = GetProcSegList(NULL,GPSLF_CLI | GPSLF_SEG);
if(segment_list == ZERO)
goto out;
if(GetSegListInfoTags(segment_list,
GSLI_ElfHandle,&__elf_handle,
TAG_DONE) != 1)
{
goto out;
}
if(__elf_handle == NULL)
goto out;
IElf = __IElf;
/* Trigger the constructors, etc. in the shared objects
linked to this binary. */
InitSHLibs(__elf_handle,TRUE);
success = TRUE;
out:
if(!success)
close_elf_library();
}
/****************************************************************************/
void void
_init(void) _init(void)
{ {
extern void shared_obj_init(void);
int num_ctors,i; int num_ctors,i;
int j; int j;
@ -162,6 +55,7 @@ _init(void)
void void
_fini(void) _fini(void)
{ {
extern void shared_obj_exit(void);
int num_dtors,i; int num_dtors,i;
static int j; static int j;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: dlfcn.h,v 1.1 2010-08-21 10:59:34 obarthel Exp $ * $Id: dlfcn.h,v 1.2 2010-08-21 11:37:03 obarthel Exp $
* *
* :ts=4 * :ts=4
* *
@ -59,10 +59,11 @@ extern "C" {
/****************************************************************************/ /****************************************************************************/
/* We only support a subset of the flags available on Unix systems. */ /* We only support a subset of the flags available on Unix systems. */
#define RTLD_LAZY 0 #define RTLD_LAZY 1
#define RTLD_NOW 0 #define RTLD_NOW 2
#define RTLD_LOCAL 4 #define RTLD_LOCAL 4
#define RTLD_GLOBAL 8 #define RTLD_GLOBAL 8
#define RTLD_DEFAULT ((void *)0)
/****************************************************************************/ /****************************************************************************/

View File

@ -1,5 +1,5 @@
# #
# $Id: libc.gmk,v 1.7 2010-08-21 10:59:34 obarthel Exp $ # $Id: libc.gmk,v 1.8 2010-08-21 11:37:03 obarthel Exp $
# #
# :ts=8 # :ts=8
# #
@ -252,6 +252,7 @@ C_LIB := \
stdlib_setjmp.o \ stdlib_setjmp.o \
stdlib_set_errno.o \ stdlib_set_errno.o \
stdlib_set_process_window.o \ stdlib_set_process_window.o \
stdlib_shared_objs.o \
stdlib_shell_escape.o \ stdlib_shell_escape.o \
stdlib_showerror.o \ stdlib_showerror.o \
stdlib_srand.o \ stdlib_srand.o \

View File

@ -1,5 +1,5 @@
/* /*
* $Id: stdlib_dlclose.c,v 1.1 2010-08-21 10:59:34 obarthel Exp $ * $Id: stdlib_dlclose.c,v 1.2 2010-08-21 11:37:03 obarthel Exp $
* *
* :ts=4 * :ts=4
* *
@ -52,10 +52,7 @@
/****************************************************************************/ /****************************************************************************/
extern struct ElfIFace * __IElf; extern struct ElfIFace * __IElf;
extern Elf32_Handle __elf_handle; extern Elf32_Handle __dl_elf_handle;
/****************************************************************************/
extern Elf32_Error __elf_error_code; extern Elf32_Error __elf_error_code;
/****************************************************************************/ /****************************************************************************/
@ -64,12 +61,12 @@ int dlclose(void * handle)
{ {
int result = -1; int result = -1;
if(__elf_handle != NULL) if(__dl_elf_handle != NULL)
{ {
struct ElfIFace * IElf = __IElf; struct ElfIFace * IElf = __IElf;
Elf32_Error error; Elf32_Error error;
error = DLClose(__elf_handle,handle); error = DLClose(__dl_elf_handle,handle);
if(error != ELF32_NO_ERROR) if(error != ELF32_NO_ERROR)
{ {
__elf_error_code = error; __elf_error_code = error;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: stdlib_dlerror.c,v 1.1 2010-08-21 10:59:34 obarthel Exp $ * $Id: stdlib_dlerror.c,v 1.2 2010-08-21 11:37:03 obarthel Exp $
* *
* :ts=4 * :ts=4
* *
@ -62,6 +62,7 @@ const char * dlerror(void)
{ {
case ELF32_NO_ERROR: case ELF32_NO_ERROR:
result = NULL;
break; break;
case ELF32_OUT_OF_MEMORY: case ELF32_OUT_OF_MEMORY:
@ -111,7 +112,7 @@ const char * dlerror(void)
case ELF32_REQUIRED_OBJECT_MISSING: case ELF32_REQUIRED_OBJECT_MISSING:
result = required object missing"; result = "required object missing";
break; break;
default: default:
@ -120,6 +121,7 @@ const char * dlerror(void)
break; break;
} }
/* Calling dlerror() will clear the error code. */
__elf_error_code = ELF32_NO_ERROR; __elf_error_code = ELF32_NO_ERROR;
return(result); return(result);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: stdlib_dlopen.c,v 1.1 2010-08-21 10:59:34 obarthel Exp $ * $Id: stdlib_dlopen.c,v 1.2 2010-08-21 11:37:03 obarthel Exp $
* *
* :ts=4 * :ts=4
* *
@ -52,7 +52,7 @@
/****************************************************************************/ /****************************************************************************/
extern struct ElfIFace * __IElf; extern struct ElfIFace * __IElf;
extern Elf32_Handle __elf_handle; extern Elf32_Handle __dl_elf_handle;
/****************************************************************************/ /****************************************************************************/
@ -88,21 +88,22 @@ void * dlopen(const char * path_name,int mode)
} }
#endif /* UNIX_PATH_SEMANTICS */ #endif /* UNIX_PATH_SEMANTICS */
if(__elf_handle != NULL) if(__dl_elf_handle != NULL)
{ {
struct ElfIFace * IElf = __IElf; struct ElfIFace * IElf = __IElf;
uint32 flags; uint32 flags = 0;
if(mode & RTLD_LOCAL) if(mode & RTLD_LOCAL)
flags = ELF32_RTLD_LOCAL; flags = ELF32_RTLD_LOCAL;
else if (mode & RTLD_GLOBAL)
flags = ELF32_RTLD_GLOBAL;
else
flags = 0;
result = DLOpen(__elf_handle,path_name,flags); if(mode & RTLD_GLOBAL)
flags = ELF32_RTLD_GLOBAL;
result = DLOpen(__dl_elf_handle,path_name,flags);
} }
out:
return(result); return(result);
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: stdlib_dlsym.c,v 1.1 2010-08-21 10:59:34 obarthel Exp $ * $Id: stdlib_dlsym.c,v 1.2 2010-08-21 11:37:03 obarthel Exp $
* *
* :ts=4 * :ts=4
* *
@ -52,25 +52,22 @@
/****************************************************************************/ /****************************************************************************/
extern struct ElfIFace * __IElf; extern struct ElfIFace * __IElf;
extern Elf32_Handle __elf_handle; extern Elf32_Handle __dl_elf_handle;
/****************************************************************************/
extern Elf32_Error __elf_error_code; extern Elf32_Error __elf_error_code;
/****************************************************************************/ /****************************************************************************/
void dlsym(void * handle,const char * symbol_name) void * dlsym(void * handle,const char * symbol_name)
{ {
void * result = NULL; void * result = NULL;
if(__elf_handle != NULL) if(__dl_elf_handle != NULL)
{ {
struct ElfIFace * IElf = __IElf; struct ElfIFace * IElf = __IElf;
APTR symbol_data = NULL; APTR symbol_data = NULL;
Elf32_Error error; Elf32_Error error;
error = DLSym(__elf_handle,handle,symbol_name,&symbol_data); error = DLSym(__dl_elf_handle,handle,symbol_name,&symbol_data);
if(error != ELF32_NO_ERROR) if(error != ELF32_NO_ERROR)
{ {
__elf_error_code = error; __elf_error_code = error;

View File

@ -1,150 +0,0 @@
/*
* $Id: stdlib_shared_libs.c,v 1.1 2010-08-20 15:33:36 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2010 by Olaf Barthel <olsen (at) sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__amigaos4__)
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard. */
/****************************************************************************/
#ifndef _STDLIB_HEADERS_H
#include "stdlib_headers.h"
#endif /* _STDLIB_HEADERS_H */
/****************************************************************************/
#ifndef _STDLIB_CONSTRUCTOR_H
#include "stdlib_constructor.h"
#endif /* _STDLIB_CONSTRUCTOR_H */
/****************************************************************************/
#include <libraries/elf.h>
#include <proto/elf.h>
#include <proto/dos.h>
/****************************************************************************/
static VOID shared_libs_init_exit(BOOL init_or_exit)
{
struct Library * ElfBase;
struct Library * DOSBase = NULL;
struct ElfIFace * IElf = NULL;
struct DOSIFace * IDOS = NULL;
BPTR segment_list;
ENTER();
/* We need elf.library V52.2 or higher. */
ElfBase = OpenLibrary("elf.library",0);
if(ElfBase == NULL || (ElfBase->lib_Version < 52) || (ElfBase->lib_Version == 52 && ElfBase->lib_Revision < 2))
goto out;
IElf = (struct ElfIFace *)GetInterface(ElfBase,"main",1,NULL);
if(IElf == NULL)
goto out;
DOSBase = OpenLibrary("dos.library",0);
if(DOSBase == NULL)
goto out;
IDOS = (struct DOSIFace *)GetInterface(DOSBase,"main",1,NULL);
if(IDOS == NULL)
goto out;
/* Try to find the Elf handle associated with this
program's segment list. */
segment_list = GetProcSegList(NULL,GPSLF_CLI | GPSLF_SEG);
if(segment_list != ZERO)
{
Elf32_Handle elf_handle = NULL;
if(GetSegListInfoTags(segment_list,
GSLI_ElfHandle,&elf_handle,
TAG_DONE) == 1)
{
/* Initialize the shared object system. Note that
we have no way of finding out whether this actually
worked... */
if(elf_handle != NULL)
InitSHLibs(elf_handle,init_or_exit);
}
}
out:
if(IDOS != NULL)
DropInterface((struct Interface *)IDOS);
if(DOSBase != NULL)
CloseLibrary(DOSBase);
if(IElf != NULL)
DropInterface((struct Interface *)IElf);
if(ElfBase != NULL)
CloseLibrary(ElfBase);
LEAVE();
}
/****************************************************************************/
CLIB_DESTRUCTOR(shared_libs_exit)
{
ENTER();
shared_libs_init_exit(FALSE);
LEAVE();
}
/****************************************************************************/
CLIB_CONSTRUCTOR(shared_libs_init)
{
ENTER();
shared_libs_init_exit(TRUE);
LEAVE();
CONSTRUCTOR_SUCCEED();
}
/****************************************************************************/
#endif /* __amigaos4__ */

View File

@ -0,0 +1,192 @@
/*
* $Id: stdlib_shared_objs.c,v 1.1 2010-08-21 11:37:03 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2010 by Olaf Barthel <olsen (at) sourcery.han.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__amigaos4__)
/****************************************************************************/
#ifndef _STDLIB_HEADERS_H
#include "stdlib_headers.h"
#endif /* _STDLIB_HEADERS_H */
/****************************************************************************/
#include <libraries/elf.h>
#include <proto/elf.h>
/****************************************************************************/
/* These are used to initialize the shared objects linked to this binary,
and for the dlopen(), dlclose() and dlsym() functions. */
struct Library * __ElfBase;
struct ElfIFace * __IElf;
/* This is used with the dlopen(), dlclose() and dlsym() functions. */
Elf32_Handle __dl_elf_handle;
/****************************************************************************/
/* This is used to initialize the shared objects only. */
static Elf32_Handle elf_handle;
/****************************************************************************/
void shared_obj_init(void);
void shared_obj_exit(void);
/****************************************************************************/
static VOID close_elf_library(void)
{
if(__IElf != NULL)
{
DropInterface((struct Interface *)__IElf);
__IElf = NULL;
}
if(__ElfBase != NULL)
{
CloseLibrary(__ElfBase);
__ElfBase = NULL;
}
}
/****************************************************************************/
static BOOL open_elf_library(void)
{
BOOL success = FALSE;
/* We need elf.library V52.2 or higher. */
__ElfBase = OpenLibrary("elf.library",0);
if(__ElfBase == NULL || (__ElfBase->lib_Version < 52) || (__ElfBase->lib_Version == 52 && __ElfBase->lib_Revision < 2))
goto out;
__IElf = (struct ElfIFace *)GetInterface(__ElfBase,"main",1,NULL);
if(__IElf == NULL)
goto out;
success = TRUE;
out:
return(success);
}
/****************************************************************************/
void shared_obj_exit(void)
{
struct ElfIFace * IElf = __IElf;
#ifndef __THREAD_SAFE
{
/* Release this program's Elf handle, if we grabbed it below. */
if(__dl_elf_handle != NULL)
{
CloseElfTags(__dl_elf_handle,
CET_ReClose,TRUE,
TAG_DONE);
__dl_elf_handle = NULL;
}
}
#endif /* __THREAD_SAFE */
/* If we got what we wanted, trigger the destructors,
etc. in the shared objects linked to this binary. */
if(elf_handle != NULL)
{
InitSHLibs(elf_handle,FALSE);
elf_handle = NULL;
}
close_elf_library();
}
/****************************************************************************/
void shared_obj_init(void)
{
if(open_elf_library())
{
struct ElfIFace * IElf = __IElf;
BPTR segment_list;
/* Try to find the Elf handle associated with this
program's segment list. */
segment_list = GetProcSegList(NULL,GPSLF_CLI | GPSLF_SEG);
if(segment_list != ZERO)
{
if(GetSegListInfoTags(segment_list,
GSLI_ElfHandle,&elf_handle,
TAG_DONE) == 1)
{
if(elf_handle != NULL)
{
/* Trigger the constructors, etc. in the shared objects
linked to this binary. */
InitSHLibs(elf_handle,TRUE);
}
}
}
/* Next: try to grab the Elf handle associated with the currently
running process. This is not thread-safe! */
#ifndef __THREAD_SAFE
{
segment_list = GetProcSegList(NULL,GPSLF_RUN);
if(segment_list != ZERO)
{
Elf32_Handle handle = NULL;
if(GetSegListInfoTags(segment_list,
GSLI_ElfHandle,&handle,
TAG_DONE) == 1)
{
if(handle != NULL)
{
__dl_elf_handle = OpenElfTags(
OET_ElfHandle,handle,
TAG_DONE);
}
}
}
}
#endif /* __THREAD_SAFE */
}
}
/****************************************************************************/
#endif /*__amigaos4__ */