auxv.c revision 211416
181634Sbrian/*- 281634Sbrian * Copyright 2010 Konstantin Belousov <kib@FreeBSD.ORG>. 381634Sbrian * All rights reserved. 481634Sbrian * 581634Sbrian * Redistribution and use in source and binary forms, with or without 681634Sbrian * modification, are permitted provided that the following conditions 781634Sbrian * are met: 881634Sbrian * 1. Redistributions of source code must retain the above copyright 981634Sbrian * notice, this list of conditions and the following disclaimer. 1081634Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1181634Sbrian * notice, this list of conditions and the following disclaimer in the 1281634Sbrian * documentation and/or other materials provided with the distribution. 1381634Sbrian * 1481634Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1581634Sbrian * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1681634Sbrian * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1781634Sbrian * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1881634Sbrian * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1981634Sbrian * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2081634Sbrian * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2181634Sbrian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2281634Sbrian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2381634Sbrian * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2481634Sbrian * 2581634Sbrian */ 2681634Sbrian 2781634Sbrian#include <sys/cdefs.h> 2881634Sbrian__FBSDID("$FreeBSD: head/lib/libc/gen/aux.c 211416 2010-08-17 09:13:26Z kib $"); 2981634Sbrian 3081634Sbrian#include "namespace.h" 3181634Sbrian#include <elf.h> 3281634Sbrian#include <errno.h> 3381634Sbrian#include <link.h> 3481634Sbrian#include <pthread.h> 35102558Sbrian#include <string.h> 36102558Sbrian#include "un-namespace.h" 3781634Sbrian#include "libc_private.h" 3881634Sbrian 3981634SbrianElf_Auxinfo *__elf_aux_vector; 4081634Sbrian 4181634Sbrianstatic pthread_once_t aux_once = PTHREAD_ONCE_INIT; 4281634Sbrian 4381634Sbrianstatic int pagesize, osreldate, canary_len, ncpus, pagesizes_len; 4481634Sbrianstatic char *canary, *pagesizes; 4581634Sbrian 46102558Sbrianstatic void 47102558Sbrianinit_aux(void) 4881634Sbrian{ 4981634Sbrian Elf_Auxinfo *aux; 5081634Sbrian 5181634Sbrian for (aux = __elf_aux_vector; aux->a_type != AT_NULL; aux++) { 5281634Sbrian switch (aux->a_type) { 5381634Sbrian case AT_CANARY: 5481634Sbrian canary = (char *)(aux->a_un.a_ptr); 5581634Sbrian break; 5681634Sbrian 5781634Sbrian case AT_CANARYLEN: 5881634Sbrian canary_len = aux->a_un.a_val; 5981634Sbrian break; 6081634Sbrian 6181634Sbrian case AT_PAGESIZES: 6281634Sbrian pagesizes = (char *)(aux->a_un.a_ptr); 6381634Sbrian break; 6481634Sbrian 6581634Sbrian case AT_PAGESIZESLEN: 6681634Sbrian pagesizes_len = aux->a_un.a_val; 6781634Sbrian break; 6881634Sbrian 6981634Sbrian case AT_PAGESZ: 7081634Sbrian pagesize = aux->a_un.a_val; 7181634Sbrian break; 7281634Sbrian 7381634Sbrian case AT_OSRELDATE: 7481634Sbrian osreldate = aux->a_un.a_val; 7581634Sbrian break; 7681634Sbrian 7781634Sbrian case AT_NCPUS: 7881634Sbrian ncpus = aux->a_un.a_val; 7981634Sbrian break; 8081634Sbrian } 8181634Sbrian } 8281634Sbrian} 8381634Sbrian 84int 85_elf_aux_info(int aux, void *buf, int buflen) 86{ 87 int res; 88 89 if (__elf_aux_vector == NULL) 90 return (ENOSYS); 91 _once(&aux_once, init_aux); 92 93 switch (aux) { 94 case AT_CANARY: 95 if (canary != NULL && canary_len >= buflen) { 96 memcpy(buf, canary, buflen); 97 memset(canary, 0, canary_len); 98 canary = NULL; 99 res = 0; 100 } else 101 res = ENOENT; 102 break; 103 case AT_PAGESIZES: 104 if (pagesizes != NULL && pagesizes_len >= buflen) { 105 memcpy(buf, pagesizes, buflen); 106 res = 0; 107 } else 108 res = ENOENT; 109 break; 110 111 case AT_PAGESZ: 112 if (buflen == sizeof(int)) { 113 if (pagesize != 0) { 114 *(int *)buf = pagesize; 115 res = 0; 116 } else 117 res = ENOENT; 118 } else 119 res = EINVAL; 120 break; 121 case AT_OSRELDATE: 122 if (buflen == sizeof(int)) { 123 if (osreldate != 0) { 124 *(int *)buf = osreldate; 125 res = 0; 126 } else 127 res = ENOENT; 128 } else 129 res = EINVAL; 130 break; 131 case AT_NCPUS: 132 if (buflen == sizeof(int)) { 133 if (ncpus != 0) { 134 *(int *)buf = ncpus; 135 res = 0; 136 } else 137 res = ENOENT; 138 } else 139 res = EINVAL; 140 break; 141 default: 142 res = ENOENT; 143 break; 144 } 145 return (res); 146} 147