Home | History | Annotate | Line # | Download | only in dlfcn
dlfcn_elf.c revision 1.10.2.1
      1  1.10.2.1     yamt /*	$NetBSD: dlfcn_elf.c,v 1.10.2.1 2012/04/17 00:05:18 yamt Exp $	*/
      2       1.1  minoura 
      3       1.1  minoura /*
      4       1.1  minoura  * Copyright (c) 2000 Takuya SHIOZAKI
      5       1.1  minoura  * All rights reserved.
      6       1.1  minoura  *
      7       1.1  minoura  * Redistribution and use in source and binary forms, with or without
      8       1.1  minoura  * modification, are permitted provided that the following conditions
      9       1.1  minoura  * are met:
     10       1.1  minoura  * 1. Redistributions of source code must retain the above copyright
     11       1.1  minoura  *    notice, this list of conditions and the following disclaimer.
     12       1.1  minoura  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1  minoura  *    notice, this list of conditions and the following disclaimer in the
     14       1.1  minoura  *    documentation and/or other materials provided with the distribution.
     15       1.1  minoura  *
     16       1.1  minoura  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17       1.1  minoura  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18       1.1  minoura  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19       1.1  minoura  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20       1.1  minoura  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21       1.1  minoura  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22       1.1  minoura  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23       1.1  minoura  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24       1.1  minoura  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25       1.1  minoura  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26       1.1  minoura  */
     27       1.1  minoura 
     28       1.1  minoura #include <sys/cdefs.h>
     29       1.1  minoura #if defined(LIBC_SCCS) && !defined(lint)
     30  1.10.2.1     yamt __RCSID("$NetBSD: dlfcn_elf.c,v 1.10.2.1 2012/04/17 00:05:18 yamt Exp $");
     31       1.1  minoura #endif /* LIBC_SCCS and not lint */
     32       1.1  minoura 
     33       1.1  minoura #include "namespace.h"
     34       1.9    joerg #include <sys/atomic.h>
     35  1.10.2.1     yamt #include <assert.h>
     36       1.8    joerg #include <elf.h>
     37       1.8    joerg #include <errno.h>
     38       1.8    joerg #include <string.h>
     39       1.9    joerg #include <stdbool.h>
     40       1.1  minoura 
     41       1.5  thorpej #undef dlopen
     42       1.5  thorpej #undef dlclose
     43       1.5  thorpej #undef dlsym
     44       1.5  thorpej #undef dlerror
     45       1.5  thorpej #undef dladdr
     46       1.6    pooka #undef dfinfo
     47       1.5  thorpej 
     48       1.5  thorpej #define	dlopen		___dlopen
     49       1.5  thorpej #define	dlclose		___dlclose
     50       1.5  thorpej #define	dlsym		___dlsym
     51      1.10   nonaka #define	dlvsym		___dlvsym
     52       1.5  thorpej #define	dlerror		___dlerror
     53       1.5  thorpej #define	dladdr		___dladdr
     54       1.6    pooka #define	dlinfo		___dlinfo
     55       1.7    skrll #define	dl_iterate_phdr		___dl_iterate_phdr
     56       1.5  thorpej 
     57       1.1  minoura #define ELFSIZE ARCH_ELFSIZE
     58       1.1  minoura #include "rtld.h"
     59       1.1  minoura 
     60       1.1  minoura #ifdef __weak_alias
     61       1.5  thorpej __weak_alias(dlopen,___dlopen)
     62       1.5  thorpej __weak_alias(dlclose,___dlclose)
     63       1.5  thorpej __weak_alias(dlsym,___dlsym)
     64      1.10   nonaka __weak_alias(dlvsym,___dlvsym)
     65       1.5  thorpej __weak_alias(dlerror,___dlerror)
     66       1.5  thorpej __weak_alias(dladdr,___dladdr)
     67       1.6    pooka __weak_alias(dlinfo,___dlinfo)
     68       1.7    skrll __weak_alias(dl_iterate_phdr,___dl_iterate_phdr)
     69       1.5  thorpej 
     70       1.5  thorpej __weak_alias(__dlopen,___dlopen)
     71       1.5  thorpej __weak_alias(__dlclose,___dlclose)
     72       1.5  thorpej __weak_alias(__dlsym,___dlsym)
     73      1.10   nonaka __weak_alias(__dlvsym,___dlvsym)
     74       1.5  thorpej __weak_alias(__dlerror,___dlerror)
     75       1.5  thorpej __weak_alias(__dladdr,___dladdr)
     76       1.6    pooka __weak_alias(__dlinfo,___dlinfo)
     77       1.7    skrll __weak_alias(__dl_iterate_phdr,___dl_iterate_phdr)
     78       1.1  minoura #endif
     79       1.1  minoura 
     80       1.4    skrll /*
     81       1.4    skrll  * For ELF, the dynamic linker directly resolves references to its
     82       1.4    skrll  * services to functions inside the dynamic linker itself.  These
     83       1.4    skrll  * weak-symbol stubs are necessary so that "ld" won't complain about
     84       1.4    skrll  * undefined symbols.  The stubs are executed only when the program is
     85       1.4    skrll  * linked statically, or when a given service isn't implemented in the
     86       1.4    skrll  * dynamic linker.  They must return an error if called, and they must
     87       1.4    skrll  * be weak symbols so that the dynamic linker can override them.
     88       1.4    skrll  */
     89       1.4    skrll 
     90       1.4    skrll static char dlfcn_error[] = "Service unavailable";
     91       1.4    skrll 
     92       1.4    skrll /*ARGSUSED*/
     93       1.4    skrll void *
     94       1.4    skrll dlopen(const char *name, int mode)
     95       1.4    skrll {
     96       1.4    skrll 
     97       1.4    skrll 	return NULL;
     98       1.4    skrll }
     99       1.4    skrll 
    100       1.4    skrll /*ARGSUSED*/
    101       1.4    skrll int
    102       1.4    skrll dlclose(void *fd)
    103       1.4    skrll {
    104       1.4    skrll 
    105       1.4    skrll 	return -1;
    106       1.4    skrll }
    107       1.4    skrll 
    108       1.4    skrll /*ARGSUSED*/
    109       1.4    skrll void *
    110       1.4    skrll dlsym(void *handle, const char *name)
    111       1.4    skrll {
    112       1.4    skrll 
    113       1.4    skrll 	return NULL;
    114       1.4    skrll }
    115       1.4    skrll 
    116       1.4    skrll /*ARGSUSED*/
    117      1.10   nonaka void *
    118      1.10   nonaka dlvsym(void *handle, const char *name, const char *version)
    119      1.10   nonaka {
    120      1.10   nonaka 
    121      1.10   nonaka 	return NULL;
    122      1.10   nonaka }
    123      1.10   nonaka 
    124      1.10   nonaka /*ARGSUSED*/
    125       1.4    skrll __aconst char *
    126       1.4    skrll dlerror()
    127       1.4    skrll {
    128       1.4    skrll 
    129       1.4    skrll 	return dlfcn_error;
    130       1.4    skrll }
    131       1.4    skrll 
    132       1.4    skrll /*ARGSUSED*/
    133       1.4    skrll int
    134       1.4    skrll dladdr(const void *addr, Dl_info *dli)
    135       1.4    skrll {
    136       1.4    skrll 
    137       1.4    skrll 	return 0;
    138       1.4    skrll }
    139       1.6    pooka 
    140       1.6    pooka /*ARGSUSED*/
    141       1.6    pooka int
    142       1.6    pooka dlinfo(void *handle, int req, void *v)
    143       1.6    pooka {
    144       1.6    pooka 
    145       1.6    pooka 	return -1;
    146       1.6    pooka }
    147       1.7    skrll 
    148       1.8    joerg static const char *dlpi_name;
    149       1.8    joerg static Elf_Addr dlpi_addr;
    150       1.8    joerg static const Elf_Phdr *dlpi_phdr;
    151       1.8    joerg static Elf_Half dlpi_phnum;
    152       1.8    joerg 
    153       1.8    joerg static void
    154       1.8    joerg dl_iterate_phdr_setup(void)
    155       1.8    joerg {
    156       1.8    joerg 	const AuxInfo *aux;
    157       1.8    joerg 
    158  1.10.2.1     yamt 	_DIAGASSERT(_dlauxinfo() != NULL);
    159       1.8    joerg 
    160  1.10.2.1     yamt 	for (aux = _dlauxinfo(); aux->a_type != AT_NULL; ++aux) {
    161       1.8    joerg 		switch (aux->a_type) {
    162       1.8    joerg 		case AT_BASE:
    163       1.8    joerg 			dlpi_addr = aux->a_v;
    164       1.8    joerg 			break;
    165       1.8    joerg 		case AT_PHDR:
    166       1.8    joerg 			dlpi_phdr = (void *)aux->a_v;
    167       1.8    joerg 			break;
    168       1.8    joerg 		case AT_PHNUM:
    169  1.10.2.1     yamt 			_DIAGASSERT(__type_fit(Elf_Half, aux->a_v));
    170  1.10.2.1     yamt 			dlpi_phnum = (Elf_Half)aux->a_v;
    171       1.8    joerg 			break;
    172       1.8    joerg 		case AT_SUN_EXECNAME:
    173       1.8    joerg 			dlpi_name = (void *)aux->a_v;
    174       1.8    joerg 			break;
    175       1.8    joerg 		}
    176       1.8    joerg 	}
    177       1.8    joerg }
    178       1.8    joerg 
    179       1.7    skrll /*ARGSUSED*/
    180       1.7    skrll int
    181       1.7    skrll dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *),
    182       1.7    skrll     void *data)
    183       1.7    skrll {
    184       1.9    joerg 	static bool setup_done;
    185       1.8    joerg 	struct dl_phdr_info phdr_info;
    186       1.8    joerg 
    187       1.9    joerg 	if (!setup_done) {
    188       1.9    joerg 		/*
    189       1.9    joerg 		 * This can race on the first call to dl_iterate_phdr.
    190       1.9    joerg 		 * dl_iterate_phdr_setup only touches field of pointer size
    191       1.9    joerg 		 * and smaller and such stores are atomic.
    192       1.9    joerg 		 */
    193       1.9    joerg 		dl_iterate_phdr_setup();
    194       1.9    joerg 		membar_producer();
    195       1.9    joerg 		setup_done = true;
    196       1.9    joerg 	}
    197       1.8    joerg 
    198       1.8    joerg 	memset(&phdr_info, 0, sizeof(phdr_info));
    199       1.8    joerg 	phdr_info.dlpi_addr = dlpi_addr;
    200       1.8    joerg 	phdr_info.dlpi_phdr = dlpi_phdr;
    201       1.8    joerg 	phdr_info.dlpi_phnum = dlpi_phnum;
    202       1.8    joerg 	phdr_info.dlpi_name = dlpi_name;
    203       1.8    joerg 
    204       1.8    joerg 	return callback(&phdr_info, sizeof(phdr_info), data);
    205       1.7    skrll }
    206