Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
with
272 additions
and 36 deletions.
- +2 −2 libexec/ld.elf_so/Makefile
- +179 −0 libexec/ld.elf_so/expand.c
- +4 −4 libexec/ld.elf_so/headers.c
- +38 −2 libexec/ld.elf_so/ld.elf_so.1
- +12 −3 libexec/ld.elf_so/load.c
- +17 −11 libexec/ld.elf_so/paths.c
- +11 −10 libexec/ld.elf_so/rtld.c
- +9 −4 libexec/ld.elf_so/rtld.h
@@ -0,0 +1,179 @@ | ||
/* $NetBSD: expand.c,v 1.1 2007/05/18 21:44:08 christos Exp $ */ | ||
|
||
/*- | ||
* Copyright (c) 2007 The NetBSD Foundation, Inc. | ||
* All rights reserved. | ||
* | ||
* This code is derived from software contributed to The NetBSD Foundation | ||
* by Christos Zoulas. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* 3. All advertising materials mentioning features or use of this software | ||
* must display the following acknowledgement: | ||
* This product includes software developed by the NetBSD | ||
* Foundation, Inc. and its contributors. | ||
* 4. Neither the name of The NetBSD Foundation nor the names of its | ||
* contributors may be used to endorse or promote products derived | ||
* from this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | ||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | ||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
#include <sys/cdefs.h> | ||
#ifndef lint | ||
__RCSID("$NetBSD: expand.c,v 1.1 2007/05/18 21:44:08 christos Exp $"); | ||
#endif /* not lint */ | ||
|
||
#include <ctype.h> | ||
#include <string.h> | ||
#include <sys/sysctl.h> | ||
|
||
#ifdef DEBUG_EXPAND | ||
#include <stdio.h> | ||
#include <err.h> | ||
#define xwarn warn | ||
size_t _rtld_expand_path(char *, size_t, const char *, const char *, | ||
const char *); | ||
#else | ||
#include <sys/stat.h> | ||
#include "rtld.h" | ||
#endif | ||
|
||
static const struct { | ||
const char *name; | ||
size_t namelen; | ||
} bltn[] = { | ||
#define ADD(a) { #a, sizeof(#a) - 1 }, | ||
ADD(HWCAP) /* SSE, MMX, etc */ | ||
ADD(ISALIST) /* uname -p */ | ||
ADD(ORIGIN) /* dirname argv[0] */ | ||
ADD(OSNAME) /* uname -s */ | ||
ADD(OSREL) /* uname -r */ | ||
ADD(PLATFORM) /* uname -m */ | ||
}; | ||
|
||
static int mib[3][2] = { | ||
{ CTL_KERN, KERN_OSTYPE }, | ||
{ CTL_KERN, KERN_OSRELEASE }, | ||
{ CTL_HW, HW_MACHINE_ARCH }, | ||
}; | ||
|
||
static size_t | ||
expand(char *buf, const char *av, int what, size_t bl) | ||
{ | ||
const char *p, *ep; | ||
char *bp = buf; | ||
size_t len; | ||
char name[32]; | ||
|
||
switch (what) { | ||
case 0: /* HWCAP XXX: Not yet */ | ||
case 1: /* ISALIST XXX: Not yet */ | ||
return 0; | ||
|
||
case 2: /* ORIGIN */ | ||
ep = strrchr(p = av, '/'); | ||
if (ep == NULL) { | ||
p = "."; | ||
ep = p + 1; | ||
} | ||
break; | ||
|
||
case 3: /* OSNAME */ | ||
case 4: /* OSREL */ | ||
case 5: /* PLATFORM */ | ||
len = sizeof(name); | ||
if (sysctl(mib[what - 3], 2, name, &len, NULL, 0) == -1) { | ||
xwarn("sysctl"); | ||
return 0; | ||
} | ||
ep = (p = name) + len - 1; | ||
break; | ||
default: | ||
return 0; | ||
} | ||
|
||
while (p != ep && bl) | ||
*bp++ = *p++, bl--; | ||
|
||
return bp - buf; | ||
} | ||
|
||
|
||
size_t | ||
_rtld_expand_path(char *buf, size_t bufsize, const char *av, const char *bp, | ||
const char *ep) | ||
{ | ||
size_t i, ds = bufsize; | ||
char *dp = buf; | ||
const char *p; | ||
int br; | ||
|
||
for (p = bp; p < ep;) { | ||
if (*p == '$') { | ||
br = *++p == '{'; | ||
|
||
if (br) | ||
p++; | ||
|
||
for (i = 0; i < sizeof(bltn) / sizeof(bltn[0]); i++) { | ||
size_t s = bltn[i].namelen; | ||
const char *es = p + s; | ||
|
||
if ((br && *es != '}') || | ||
(!br && (es != ep && | ||
isalpha((unsigned char)*es)))) | ||
continue; | ||
|
||
if (strncmp(bltn[i].name, p, s) == 0) { | ||
size_t ls = expand(dp, av, i, ds); | ||
if (ls >= ds) | ||
return bufsize; | ||
ds -= ls; | ||
dp += ls; | ||
p = es + br; | ||
goto done; | ||
} | ||
} | ||
p -= br + 1; | ||
|
||
} | ||
*dp++ = *p++; | ||
ds--; | ||
done:; | ||
} | ||
*dp = '\0'; | ||
return dp - buf; | ||
} | ||
|
||
#ifdef DEBUG_EXPAND | ||
int | ||
main(int argc, char *argv[]) | ||
{ | ||
char buf[1024]; | ||
size_t i; | ||
|
||
for (i = 1; i < argc; i++) { | ||
char *p = argv[i], *ep = argv[i] + strlen(p); | ||
size_t n = _rtld_expand_path(buf, sizeof(buf), argv[0], p, ep); | ||
printf("%s\n", buf); | ||
} | ||
return 0; | ||
} | ||
#endif |
Oops, something went wrong.