[BACK]Return to dlfcn_elf.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / dlfcn

Annotation of src/lib/libc/dlfcn/dlfcn_elf.c, Revision 1.15.2.1

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

CVSweb <webmaster@jp.NetBSD.org>