diff options
Diffstat (limited to 'dl')
-rw-r--r-- | dl/dl_gnu.go | 91 | ||||
-rw-r--r-- | dl/dlfcn.go | 62 | ||||
-rw-r--r-- | dl/dlsym_reserved.go | 63 |
3 files changed, 172 insertions, 44 deletions
diff --git a/dl/dl_gnu.go b/dl/dl_gnu.go index c7c409b..99ec32c 100644 --- a/dl/dl_gnu.go +++ b/dl/dl_gnu.go @@ -1,44 +1,69 @@ -package dl +// The code in this file is trivial, and not eligable for copyright. +// +// The documentation in this file is taken from the Linux Programmer's +// Manual page for dlopen(3). +// +// Copyright 1995 Yggdrasil Computing, Incorporated. +// written by Adam J. Richter (adam@yggdrasil.com), +// with typesetting help from Daniel Quinlan (quinlan@yggdrasil.com). +// and Copyright 2003, 2015 Michael Kerrisk (mtk.manpages@gmail.com). +// +// This is free documentation; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The GNU General Public License's references to "object code" +// and "executables" are to be interpreted as the output of any +// document formatting or typesetting system, including +// intermediate and printed output. +// +// This manual 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this manual; if not, see +// <http://www.gnu.org/licenses/>. +// +// Modified by David A. Wheeler <dwheeler@dwheeler.com> 2000-11-28. +// Applied patch by Terran Melconian, aeb, 2001-12-14. +// Modified by Hacksaw <hacksaw@hacksaw.org> 2003-03-13. +// Modified by Matt Domsch, 2003-04-09: _init and _fini obsolete +// Modified by Michael Kerrisk <mtk.manpages@gmail.com> 2003-05-16. +// Modified by Walter Harms: dladdr, dlvsym +// Modified by Petr Baudis <pasky@suse.cz>, 2008-12-04: dladdr caveat -import "unsafe" +package dl //#define _GNU_SOURCE -//#include <stdlib.h> -//#include <stdint.h> //#include <dlfcn.h> -//const uintptr_t rtld_next = (uintptr_t)RTLD_NEXT; -//const uintptr_t rtld_default = (uintptr_t)RTLD_DEFAULT; import "C" +// These flags to Open() are GNU libc extensions. const ( - RTLD_NOLOAD Flag = C.RTLD_NOLOAD - RTLD_NODELETE Flag = C.RTLD_NODELETE - RTLD_DEEPBIND Flag = C.RTLD_DEEPBIND -) + // Do not unload the shared object during Close(). + // Consequently, the object's static variables are not + // reinitialized if the object is reloaded with Open() at a + // later time. + RTLD_NODELETE Flag = C.RTLD_NODELETE // (since glibc 2.2, also present on Solaris) -// These are kinda weird in that they aren't required by the standard, -// but they are reserved by the standard (see the documentation for -// `dlsym(3)`). On glibc, it takes _GNU_SOURCE to get them. -// -// There are two special pseudo-handles that may be specified -// in handle: -var ( - RTLD_DEFAULT Handle = Handle{unsafe.Pointer(uintptr(C.rtld_default))} - // Find the first occurrence of the desired symbol using - // the default shared object search order. The search will - // include global symbols in the executable and its - // dependencies, as well as symbols in shared objects that - // were dynamically loaded with the RTLD_GLOBAL flag. - RTLD_NEXT Handle = Handle{unsafe.Pointer(uintptr(C.rtld_next))} - // Find the next occurrence of the desired symbol in the - // search order after the current object. This allows one - // to provide a wrapper around a function in another shared - // object, so that, for example, the definition of a - // function in a preloaded shared object (see LD_PRELOAD in - // ld.so(8)) can find and invoke the "real" function - // provided in another shared object (or for that matter, - // the "next" definition of the function in cases where - // there are multiple layers of preloading). + // Don't load the shared object. This can be used to test if + // the object is already resident (Open() returns nil if it + // is not, or the object's handle if it is resident). This + // flag can also be used to promote the flags on a shared + // object that is already loaded. For example, a shared + // object that was previously loaded with RTLD_LOCAL can be + // reopened with RTLD_NOLOAD | RTLD_GLOBAL. + RTLD_NOLOAD Flag = C.RTLD_NOLOAD // (since glibc 2.2, also present on Solaris) + + // Place the lookup scope of the symbols in this shared object + // ahead of the global scope. This means that a + // self-contained object will use its own symbols in + // preference to global symbols with the same name contained + // in objects that have already been loaded. + RTLD_DEEPBIND Flag = C.RTLD_DEEPBIND // (since glibc 2.3.4) ) // TODO: dlmopen diff --git a/dl/dlfcn.go b/dl/dlfcn.go index d5467f3..3ab5abb 100644 --- a/dl/dlfcn.go +++ b/dl/dlfcn.go @@ -1,3 +1,25 @@ +// Copyright 2015 Luke Shumaker <lukeshu@sbcglobal.net>. +// +// This is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The GNU General Public License's references to "object code" and +// "executables" are to be interpreted to also include the output of +// any document formatting or typesetting system, including +// intermediate and printed output. +// +// This software 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this manual; if not, see +// <http://www.gnu.org/licenses/>. + +// Package dl provides an interface to the POSIX runtime linker. package dl import ( @@ -12,26 +34,39 @@ import "C" type Flag int +// POSIX specifies these four flags to Open(). const ( - RTLD_LAZY Flag = C.RTLD_LAZY // Relocations are performed at an - // implementation-defined time. - RTLD_NOW Flag = C.RTLD_NOW // Relocations are performed when the - // object is loaded. - RTLD_GLOBAL Flag = C.RTLD_GLOBAL // All symbols are available for - // relocation processing of other - // modules. - RTLD_LOCAL Flag = C.RTLD_LOCAL // All symbols are not made available - // for relocation processing by other - // modules. + // Relocations are performed at an implementation-defined + // time. + RTLD_LAZY Flag = C.RTLD_LAZY + + // Relocations are performed when the object is loaded. + RTLD_NOW Flag = C.RTLD_NOW + + // All symbols are available for relocation processing of + // other modules. + RTLD_GLOBAL Flag = C.RTLD_GLOBAL + + // All symbols are not made available for relocation + // processing by other modules. + RTLD_LOCAL Flag = C.RTLD_LOCAL ) type Handle struct { c unsafe.Pointer } +// Open a shared object file, returning a Handle to it, or an error. +// If name is an empty string, then the returned handle is the global +// symbol table for the current process; if the name contains a slash, +// then it is interpretted as a pathname; otherwise, it is +// interpretted in an implementation-defined manner. func Open(name string, flags Flag) (Handle, error) { nameC := C.CString(name) defer C.free(unsafe.Pointer(nameC)) + if name == "" { + nameC = nil + } dlerror() ptr := C.dlopen(nameC, C.int(flags)) @@ -41,8 +76,10 @@ func Open(name string, flags Flag) (Handle, error) { return Handle{ptr}, nil } +// Look up a symbol, and return a pointer to it. +// // This returns uintptr instead of unsafe.Pointer so that code using -// reflect cannot obtain unsafe.Pointers without importing the unsafe +// dl cannot obtain unsafe.Pointers without importing the unsafe // package explicitly. func (h Handle) Sym(symbol string) (uintptr, error) { symbolC := C.CString(symbol) @@ -56,6 +93,9 @@ func (h Handle) Sym(symbol string) (uintptr, error) { return uintptr(ptr), nil } +// Close this handle on a shared object; decrementint the reference +// count; if the reference count drops below 0, then the object is +// unloaded. func (h Handle) Close() error { dlerror() r := C.dlclose(h.c) diff --git a/dl/dlsym_reserved.go b/dl/dlsym_reserved.go new file mode 100644 index 0000000..081e012 --- /dev/null +++ b/dl/dlsym_reserved.go @@ -0,0 +1,63 @@ +// The documentation for RTLD_DEFAULT and RTLD_NEXT is taken from the +// Linux Programmer's Manual page for dlsym(3). +// +// Copyright 1995 Yggdrasil Computing, Incorporated. +// Copyright 2003, 2015 Michael Kerrisk <mtk.manpages@gmail.com>. +// Copyright 2015 Luke Shumaker <lukeshu@sbcglobal.net>. +// +// This is free documentation; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The GNU General Public License's references to "object code" +// and "executables" are to be interpreted as the output of any +// document formatting or typesetting system, including +// intermediate and printed output. +// +// This manual 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this manual; if not, see +// <http://www.gnu.org/licenses/>. + +package dl + +import "unsafe" + +//#define _GNU_SOURCE +//#include <stdint.h> +//#include <dlfcn.h> +//const uintptr_t rtld_next = (uintptr_t)RTLD_NEXT; +//const uintptr_t rtld_default = (uintptr_t)RTLD_DEFAULT; +import "C" + +// These constant values for Handles are reserved by POSIX for future +// use with these meanings. They are available in GNU libdl if +// _GNU_SOURCE is defined. +var ( + // This Handle represents the default default shared object + // search order. The search will include global symbols in + // the executable and its dependencies, as well as symbols in + // shared objects that were dynamically loaded with the + // RTLD_GLOBAL flag. + RTLD_DEFAULT Handle + + // This Handle represents the shared object search order after + // the current object. This allows one to provide a wrapper + // around a function in another shared object, so that, for + // example, the definition of a function in a preloaded shared + // object (see LD_PRELOAD in ld.so(8)) can find and invoke the + // "real" function provided in another shared object (or for + // that matter, the "next" definition of the function in cases + // where there are multiple layers of preloading). + RTLD_NEXT Handle +) + +func init() { + RTLD_DEFAULT = Handle{c: unsafe.Pointer(uintptr(C.rtld_default)), o: 2} + RTLD_DEFAULT = Handle{c: unsafe.Pointer(uintptr(C.rtld_next)), o: 2} +} |