From 1bdfc0d143395343be4a47a506bf0be404732638 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Sat, 21 Aug 2010 10:59:34 +0000 Subject: [PATCH] - 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. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@15206 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/changes | 4 ++ library/include/dlfcn.h | 86 ++++++++++++++++++++++++++ library/libc.gmk | 6 +- library/libunix.gmk | 3 +- library/stdlib_dlclose.c | 89 +++++++++++++++++++++++++++ library/stdlib_dlerror.c | 130 +++++++++++++++++++++++++++++++++++++++ library/stdlib_dlopen.c | 111 +++++++++++++++++++++++++++++++++ library/stdlib_dlsym.c | 90 +++++++++++++++++++++++++++ 8 files changed, 517 insertions(+), 2 deletions(-) create mode 100644 library/include/dlfcn.h create mode 100644 library/stdlib_dlclose.c create mode 100644 library/stdlib_dlerror.c create mode 100644 library/stdlib_dlopen.c create mode 100644 library/stdlib_dlsym.c diff --git a/library/changes b/library/changes index 3785c92..9574dde 100644 --- a/library/changes +++ b/library/changes @@ -1,3 +1,7 @@ +- 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. + - The shared object initialization has to be performed before any local constructors are invoked, and after all local destructors have been invoked. diff --git a/library/include/dlfcn.h b/library/include/dlfcn.h new file mode 100644 index 0000000..e1c1a7e --- /dev/null +++ b/library/include/dlfcn.h @@ -0,0 +1,86 @@ +/* + * $Id: dlfcn.h,v 1.1 2010-08-21 10:59:34 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2010 by Olaf Barthel + * 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. + * + ***************************************************************************** + * + * Documentation and source code for this library, and the most recent library + * build are available from . + * + ***************************************************************************** + */ + +#ifndef _DLFCN_H +#define _DLFCN_H + +/****************************************************************************/ + +/* The following is not part of the ISO 'C' (1994) standard. */ + +/****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/****************************************************************************/ + +/* The shared object API is available only on AmigaOS 4.0. */ +#if defined(__amigaos4__) + +/****************************************************************************/ + +/* We only support a subset of the flags available on Unix systems. */ +#define RTLD_LAZY 0 +#define RTLD_NOW 0 +#define RTLD_LOCAL 4 +#define RTLD_GLOBAL 8 + +/****************************************************************************/ + +extern int dlclose(void * __handle); +extern const char * dlerror(void); +extern void * dlopen(const char * __path_name,int __mode); +extern void * dlsym(void * __handle,const char * __symbol_name); + +/****************************************************************************/ + +#endif /* __amigaos4__ */ + +/****************************************************************************/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/****************************************************************************/ + +#endif /* _DLFCN_H */ diff --git a/library/libc.gmk b/library/libc.gmk index 13d630c..f0cd2e8 100755 --- a/library/libc.gmk +++ b/library/libc.gmk @@ -1,5 +1,5 @@ # -# $Id: libc.gmk,v 1.6 2010-08-21 09:57:50 obarthel Exp $ +# $Id: libc.gmk,v 1.7 2010-08-21 10:59:34 obarthel Exp $ # # :ts=8 # @@ -205,6 +205,10 @@ C_LIB := \ stdlib_div.o \ stdlib_divsi3.o \ stdlib_divsi4.o \ + stdlib_dlclose.o \ + stdlib_dlerror.o \ + stdlib_dlopen.o \ + stdlib_dlsym.o \ stdlib_dosbase.o \ stdlib_exit.o \ stdlib_free.o \ diff --git a/library/libunix.gmk b/library/libunix.gmk index 41e1d1b..de264a1 100755 --- a/library/libunix.gmk +++ b/library/libunix.gmk @@ -1,5 +1,5 @@ # -# $Id: libunix.gmk,v 1.3 2006-11-13 09:25:28 obarthel Exp $ +# $Id: libunix.gmk,v 1.4 2010-08-21 10:59:34 obarthel Exp $ # # :ts=8 # @@ -57,6 +57,7 @@ UNIX_LIB := \ stdlib_alloca_cleanup.o \ stdlib_alloca_trap.o \ stdlib_arg.o \ + stdlib_dlopen.o \ stdlib_expand_wildcard.o \ stdlib_expand_wildcard_check.o \ stdlib_getmemstats.o \ diff --git a/library/stdlib_dlclose.c b/library/stdlib_dlclose.c new file mode 100644 index 0000000..95dabef --- /dev/null +++ b/library/stdlib_dlclose.c @@ -0,0 +1,89 @@ +/* + * $Id: stdlib_dlclose.c,v 1.1 2010-08-21 10:59:34 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2010 by Olaf Barthel + * 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. + */ + +#ifndef _STDLIB_HEADERS_H +#include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +/****************************************************************************/ + +/* The shared object API is available only on AmigaOS 4.0. */ +#if defined(__amigaos4__) + +/****************************************************************************/ + +#include + +/****************************************************************************/ + +#include +#include + +/****************************************************************************/ + +extern struct ElfIFace * __IElf; +extern Elf32_Handle __elf_handle; + +/****************************************************************************/ + +extern Elf32_Error __elf_error_code; + +/****************************************************************************/ + +int dlclose(void * handle) +{ + int result = -1; + + if(__elf_handle != NULL) + { + struct ElfIFace * IElf = __IElf; + Elf32_Error error; + + error = DLClose(__elf_handle,handle); + if(error != ELF32_NO_ERROR) + { + __elf_error_code = error; + goto out; + } + } + + result = 0; + + out: + + return(result); +} + +/****************************************************************************/ + +#endif /* __amigaos4__ */ diff --git a/library/stdlib_dlerror.c b/library/stdlib_dlerror.c new file mode 100644 index 0000000..e45beeb --- /dev/null +++ b/library/stdlib_dlerror.c @@ -0,0 +1,130 @@ +/* + * $Id: stdlib_dlerror.c,v 1.1 2010-08-21 10:59:34 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2010 by Olaf Barthel + * 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. + */ + +#ifndef _STDLIB_HEADERS_H +#include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +/****************************************************************************/ + +/* The shared object API is available only on AmigaOS 4.0. */ +#if defined(__amigaos4__) + +/****************************************************************************/ + +#include + +/****************************************************************************/ + +#include + +/****************************************************************************/ + +extern Elf32_Error __elf_error_code; + +/****************************************************************************/ + +const char * dlerror(void) +{ + const char * result; + + switch(__elf_error_code) + { + case ELF32_NO_ERROR: + + break; + + case ELF32_OUT_OF_MEMORY: + + result = "out of memory"; + break; + + case ELF32_INVALID_HANDLE: + + result = "invalid handle"; + break; + + case ELF32_NO_MORE_RELOCS: + + result = "no more relocs"; + break; + + case ELF32_SECTION_NOT_LOADED: + + result = "section not loaded"; + break; + + case ELF32_UNKNOWN_RELOC: + + result = "unknown reloc"; + break; + + case ELF32_READ_ERROR: + + result = "read error"; + break; + + case ELF32_INVALID_SDA_BASE: + + result = "invalid SDA base"; + break; + + case ELF32_SYMBOL_NOT_FOUND: + + result = "symbol not found"; + break; + + case ELF32_INVALID_NAME: + + result = "invalid name"; + break; + + case ELF32_REQUIRED_OBJECT_MISSING: + + result = required object missing"; + break; + + default: + + result = "unknown error"; + break; + } + + __elf_error_code = ELF32_NO_ERROR; + + return(result); +} + +/****************************************************************************/ + +#endif /* __amigaos4__ */ diff --git a/library/stdlib_dlopen.c b/library/stdlib_dlopen.c new file mode 100644 index 0000000..fe7a041 --- /dev/null +++ b/library/stdlib_dlopen.c @@ -0,0 +1,111 @@ +/* + * $Id: stdlib_dlopen.c,v 1.1 2010-08-21 10:59:34 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2010 by Olaf Barthel + * 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. + */ + +#ifndef _STDLIB_HEADERS_H +#include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +/****************************************************************************/ + +/* The shared object API is available only on AmigaOS 4.0. */ +#if defined(__amigaos4__) + +/****************************************************************************/ + +#include + +/****************************************************************************/ + +#include +#include + +/****************************************************************************/ + +extern struct ElfIFace * __IElf; +extern Elf32_Handle __elf_handle; + +/****************************************************************************/ + +void * dlopen(const char * path_name,int mode) +{ + #if defined(UNIX_PATH_SEMANTICS) + struct name_translation_info path_name_nti; + #endif /* UNIX_PATH_SEMANTICS */ + + void * result = NULL; + + #if defined(UNIX_PATH_SEMANTICS) + { + if(__unix_path_semantics) + { + if(path_name[0] == '\0') + { + SHOWMSG("no name given"); + + __set_errno(ENOENT); + goto out; + } + + if(__translate_unix_to_amiga_path_name(&path_name,&path_name_nti) != 0) + goto out; + + if(path_name_nti.is_root) + { + __set_errno(EACCES); + goto out; + } + } + } + #endif /* UNIX_PATH_SEMANTICS */ + + if(__elf_handle != NULL) + { + struct ElfIFace * IElf = __IElf; + uint32 flags; + + if(mode & 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); + } + + return(result); +} + +/****************************************************************************/ + +#endif /* __amigaos4__ */ diff --git a/library/stdlib_dlsym.c b/library/stdlib_dlsym.c new file mode 100644 index 0000000..a9f6ccf --- /dev/null +++ b/library/stdlib_dlsym.c @@ -0,0 +1,90 @@ +/* + * $Id: stdlib_dlsym.c,v 1.1 2010-08-21 10:59:34 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2010 by Olaf Barthel + * 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. + */ + +#ifndef _STDLIB_HEADERS_H +#include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +/****************************************************************************/ + +/* The shared object API is available only on AmigaOS 4.0. */ +#if defined(__amigaos4__) + +/****************************************************************************/ + +#include + +/****************************************************************************/ + +#include +#include + +/****************************************************************************/ + +extern struct ElfIFace * __IElf; +extern Elf32_Handle __elf_handle; + +/****************************************************************************/ + +extern Elf32_Error __elf_error_code; + +/****************************************************************************/ + +void dlsym(void * handle,const char * symbol_name) +{ + void * result = NULL; + + if(__elf_handle != NULL) + { + struct ElfIFace * IElf = __IElf; + APTR symbol_data = NULL; + Elf32_Error error; + + error = DLSym(__elf_handle,handle,symbol_name,&symbol_data); + if(error != ELF32_NO_ERROR) + { + __elf_error_code = error; + goto out; + } + + result = symbol_data; + } + + out: + + return(result); +} + +/****************************************************************************/ + +#endif /* __amigaos4__ */