2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright 2010, 2012 Konstantin Belousov <kib@FreeBSD.ORG>.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include "namespace.h"
39 #include "un-namespace.h"
40 #include "libc_private.h"
42 extern char **environ;
46 void *__elf_aux_vector;
47 static pthread_once_t aux_vector_once = PTHREAD_ONCE_INIT;
50 init_aux_vector_once(void)
54 sp = (Elf_Addr *)environ;
57 __elf_aux_vector = (Elf_Auxinfo *)sp;
61 __init_elf_aux_vector(void)
64 if (&_DYNAMIC != NULL)
66 _once(&aux_vector_once, init_aux_vector_once);
69 static pthread_once_t aux_once = PTHREAD_ONCE_INIT;
70 static int pagesize, osreldate, canary_len, ncpus, pagesizes_len;
71 static int hwcap_present, hwcap2_present;
72 static char *canary, *pagesizes;
73 static void *timekeep;
74 static u_long hwcap, hwcap2;
81 for (aux = __elf_aux_vector; aux->a_type != AT_NULL; aux++) {
82 switch (aux->a_type) {
84 canary = (char *)(aux->a_un.a_ptr);
88 canary_len = aux->a_un.a_val;
93 hwcap = (u_long)(aux->a_un.a_val);
98 hwcap2 = (u_long)(aux->a_un.a_val);
102 pagesizes = (char *)(aux->a_un.a_ptr);
105 case AT_PAGESIZESLEN:
106 pagesizes_len = aux->a_un.a_val;
110 pagesize = aux->a_un.a_val;
114 osreldate = aux->a_un.a_val;
118 ncpus = aux->a_un.a_val;
122 timekeep = aux->a_un.a_ptr;
128 __weak_reference(_elf_aux_info, elf_aux_info);
131 _elf_aux_info(int aux, void *buf, int buflen)
135 __init_elf_aux_vector();
136 if (__elf_aux_vector == NULL)
138 _once(&aux_once, init_aux);
142 if (canary != NULL && canary_len >= buflen) {
143 memcpy(buf, canary, buflen);
144 memset(canary, 0, canary_len);
151 if (hwcap_present && buflen == sizeof(u_long)) {
152 *(u_long *)buf = hwcap;
158 if (hwcap2_present && buflen == sizeof(u_long)) {
159 *(u_long *)buf = hwcap2;
165 if (pagesizes != NULL && pagesizes_len >= buflen) {
166 memcpy(buf, pagesizes, buflen);
172 if (buflen == sizeof(int)) {
174 *(int *)buf = pagesize;
182 if (buflen == sizeof(int)) {
183 if (osreldate != 0) {
184 *(int *)buf = osreldate;
192 if (buflen == sizeof(int)) {
202 if (buflen == sizeof(void *)) {
203 if (timekeep != NULL) {
204 *(void **)buf = timekeep;