1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include "lint.h" 28 #include <libc.h> 29 #include <fcntl.h> 30 #include <stdlib.h> 31 #include <unistd.h> 32 #include <sys/types.h> 33 #include <sys/stat.h> 34 #include <sys/auxv.h> 35 #include <mtlib.h> 36 #include <thread.h> 37 #include <synch.h> 38 #include <atomic.h> 39 40 static mutex_t auxlock = DEFAULTMUTEX; 41 42 /* 43 * Get auxiliary entry. 44 * Returns pointer to entry, or 0 if entry does not exist. 45 */ 46 static auxv_t * 47 _getaux(int type) 48 { 49 static auxv_t *auxb = NULL; 50 static size_t nauxv = 0; 51 ssize_t i; 52 53 /* 54 * The first time through, read the initial aux vector that was 55 * passed to the process at exec(2). Only do this once. 56 */ 57 if (auxb == NULL) { 58 lmutex_lock(&auxlock); 59 if (auxb == NULL) { 60 struct stat statb; 61 auxv_t *buf = NULL; 62 int fd; 63 64 if ((fd = open("/proc/self/auxv", O_RDONLY)) != -1 && 65 fstat(fd, &statb) != -1) 66 buf = libc_malloc( 67 statb.st_size + sizeof (auxv_t)); 68 69 if (buf != NULL) { 70 i = read(fd, buf, statb.st_size); 71 if (i != -1) { 72 nauxv = i / sizeof (auxv_t); 73 buf[nauxv].a_type = AT_NULL; 74 } else { 75 libc_free(buf); 76 buf = NULL; 77 } 78 } 79 80 if (fd != -1) 81 (void) close(fd); 82 83 membar_producer(); 84 auxb = buf; 85 } 86 lmutex_unlock(&auxlock); 87 } 88 membar_consumer(); 89 90 /* 91 * Scan the auxiliary entries looking for the required type. 92 */ 93 for (i = 0; i < nauxv; i++) 94 if (auxb[i].a_type == type) 95 return (&auxb[i]); 96 97 /* 98 * No auxiliary array (static executable) or entry not found. 99 */ 100 return ((auxv_t *)0); 101 } 102 103 /* 104 * These two routines are utilities exported to the rest of libc. 105 */ 106 107 long 108 ___getauxval(int type) 109 { 110 auxv_t *auxp; 111 112 if ((auxp = _getaux(type)) != (auxv_t *)0) 113 return (auxp->a_un.a_val); 114 return (0); 115 } 116 117 void * 118 ___getauxptr(int type) 119 { 120 auxv_t *auxp; 121 122 if ((auxp = _getaux(type)) != (auxv_t *)0) 123 return (auxp->a_un.a_ptr); 124 return (0); 125 } 126