nrelease - fix/improve livecd
[dragonfly.git] / lib / libc / gen / dlfcn.c
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1998 John D. Polstra
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
fcf53d9b 26 * $FreeBSD: src/lib/libc/gen/dlfcn.c 217154 2011-01-08 17:13:43Z kib $
984263bc
MD
27 */
28
e9de6dcc 29#include <sys/mman.h>
984263bc 30#include <dlfcn.h>
fcf53d9b 31#include <link.h>
984263bc 32#include <stddef.h>
e3b4bb34 33#include <string.h>
f45ae2bf
SW
34#include "libc_private.h"
35
6ba1d1f2 36struct dl_phdr_info build_phdr_info(void) __dso_hidden;
f45ae2bf
SW
37void _rtld_thread_childfork(void);
38void _rtld_thread_init(void *);
39void _rtld_thread_postfork(void);
40void _rtld_thread_prefork(void);
50caca1a 41void _rtld_setthreaded(void);
984263bc 42
f0a144b4 43extern char **environ;
4ce464e1 44
fcf53d9b 45static char sorry[] = "Service unavailable";
984263bc
MD
46
47/*
48 * For ELF, the dynamic linker directly resolves references to its
49 * services to functions inside the dynamic linker itself. These
50 * weak-symbol stubs are necessary so that "ld" won't complain about
51 * undefined symbols. The stubs are executed only when the program is
52 * linked statically, or when a given service isn't implemented in the
53 * dynamic linker. They must return an error if called, and they must
54 * be weak symbols so that the dynamic linker can override them.
55 */
56
57#pragma weak _rtld_error
58void
4ce464e1 59_rtld_error(const char *fmt __unused, ...)
984263bc
MD
60{
61}
62
63#pragma weak dladdr
64int
4ce464e1 65dladdr(const void *addr __unused, Dl_info *dlip __unused)
984263bc
MD
66{
67 _rtld_error(sorry);
68 return 0;
69}
70
71#pragma weak dlclose
72int
4ce464e1 73dlclose(void *handle __unused)
984263bc
MD
74{
75 _rtld_error(sorry);
76 return -1;
77}
78
79#pragma weak dlerror
fcf53d9b 80char *
984263bc
MD
81dlerror(void)
82{
83 return sorry;
84}
85
984263bc
MD
86#pragma weak dlopen
87void *
4ce464e1 88dlopen(const char *name __unused, int mode __unused)
984263bc
MD
89{
90 _rtld_error(sorry);
91 return NULL;
92}
93
94#pragma weak dlsym
95void *
4ce464e1 96dlsym(void *handle __unused, const char *name __unused)
984263bc
MD
97{
98 _rtld_error(sorry);
99 return NULL;
100}
101
fcf53d9b
JM
102#pragma weak dlfunc
103dlfunc_t
104dlfunc(void * handle __unused, const char * name __unused)
105{
106 _rtld_error(sorry);
107 return NULL;
108}
109
110#pragma weak dlvsym
111void *
112dlvsym(void *handle __unused,const char *name __unused,
113 const char *version __unused)
114{
115 _rtld_error(sorry);
116 return NULL;
117}
118
847f4e75
JM
119#pragma weak _rtld_thread_init
120void
5dcdf778 121_rtld_thread_init(void * li __unused)
847f4e75
JM
122{
123 _rtld_error(sorry);
124}
125
984263bc
MD
126#pragma weak dlinfo
127int
4ce464e1 128dlinfo(void *handle __unused, int request __unused, void *p __unused)
984263bc
MD
129{
130 _rtld_error(sorry);
3641b7ca 131 return 0;
984263bc 132}
fcf53d9b 133
6ba1d1f2 134struct dl_phdr_info
f0a144b4
JM
135build_phdr_info(void)
136{
137 struct dl_phdr_info phdr_info;
138 Elf_Addr *sp;
139 Elf_Auxinfo *aux, *auxp;
f0a144b4
JM
140 unsigned int i;
141
142 sp = (Elf_Addr *) environ;
143 while (*sp++ != 0)
144 ;
145 aux = (Elf_Auxinfo *) sp;
f0a144b4
JM
146 memset (&phdr_info, 0, sizeof(phdr_info));
147 for (auxp = aux; auxp->a_type != AT_NULL; auxp++) {
148 switch (auxp->a_type) {
149 case AT_BASE:
150 phdr_info.dlpi_addr = (Elf_Addr) auxp->a_un.a_ptr;
151 break;
f0a144b4
JM
152 case AT_EXECPATH:
153 phdr_info.dlpi_name = (const char *) auxp->a_un.a_ptr;
154 break;
f0a144b4
JM
155 case AT_PHDR:
156 phdr_info.dlpi_phdr = (const Elf_Phdr *) auxp->a_un.a_ptr;
157 break;
f0a144b4
JM
158 case AT_PHNUM:
159 phdr_info.dlpi_phnum = (Elf_Half) auxp->a_un.a_val;
160 break;
161 }
162 }
163
164 for (i = 0; i < phdr_info.dlpi_phnum; i++)
165 if (phdr_info.dlpi_phdr[i].p_type == PT_TLS) {
166 phdr_info.dlpi_tls_modid = 1;
167 phdr_info.dlpi_tls_data =
752fcd15 168 (void*)phdr_info.dlpi_phdr[i].p_vaddr;
f0a144b4
JM
169 }
170
171 return (phdr_info);
172}
173
fcf53d9b
JM
174#pragma weak dl_iterate_phdr
175int
176dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *),
177 void *data)
178{
e3b4bb34 179 static int seen = 0;
f0a144b4
JM
180 static struct dl_phdr_info phdr_info;
181 if (!seen) {
182 seen = 1;
183 phdr_info = build_phdr_info();
184 }
185
186 return callback(&phdr_info, sizeof(phdr_info), data);
fcf53d9b
JM
187}
188
d679f65e 189#pragma weak fdlopen
303c1887 190void *
6d7019e6 191fdlopen(int fd __unused, int mode __unused)
303c1887 192{
752fcd15
JM
193 _rtld_error(sorry);
194 return NULL;
303c1887
JM
195}
196
fcf53d9b
JM
197#pragma weak _rtld_addr_phdr
198int
6d7019e6
SW
199_rtld_addr_phdr(const void *addr __unused,
200 struct dl_phdr_info *phdr_info __unused)
fcf53d9b
JM
201{
202
203 return (0);
204}
205
e9de6dcc
JM
206#pragma weak _rtld_get_stack_prot
207int
208_rtld_get_stack_prot(void)
209{
210 return (PROT_EXEC | PROT_READ | PROT_WRITE);
211}
f53c59ab
MD
212
213#pragma weak _rtld_thread_prefork
214void
215_rtld_thread_prefork(void)
216{
217}
218
219#pragma weak _rtld_thread_postfork
220void
221_rtld_thread_postfork(void)
222{
223}
224
225#pragma weak _rtld_thread_childfork
226void
227_rtld_thread_childfork(void)
228{
229}
50caca1a
MD
230
231#pragma weak _rtld_setthreaded
50caca1a
MD
232void
233_rtld_setthreaded(void)
234{
235}