Make ld.elf_so use the new sysctl API. That allows the user to give any
sysctl variable name in /etc/ld.so.conf. It also makes the ld.elf_so binary slightly smaller (at least on i386), and has no impact on performance. Fixes PR 26100.
This commit is contained in:
parent
2e61c89539
commit
d1b3d841ee
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: load.c,v 1.27 2003/11/25 14:36:49 christos Exp $ */
|
||||
/* $NetBSD: load.c,v 1.28 2004/07/05 11:50:07 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -179,6 +179,7 @@ _rtld_load_by_name(const char *name, Obj_Entry *obj, Needed_Entry **needed, int
|
||||
bool got = false;
|
||||
union {
|
||||
int i;
|
||||
u_quad_t q;
|
||||
char s[16];
|
||||
} val;
|
||||
|
||||
@ -187,22 +188,24 @@ _rtld_load_by_name(const char *name, Obj_Entry *obj, Needed_Entry **needed, int
|
||||
if (strcmp(x->name, name) != 0)
|
||||
continue;
|
||||
|
||||
i = sizeof(val);
|
||||
|
||||
if (sysctl(x->ctl, x->ctlmax, &val, &i, NULL, 0) == -1) {
|
||||
xwarnx(_PATH_LD_HINTS ": unknown sysctl for %s", name);
|
||||
j = sizeof(val);
|
||||
if ((i = _rtld_sysctl(x->ctlname, &val, &j)) == -1) {
|
||||
xwarnx(_PATH_LD_HINTS ": invalid/unknown sysctl for %s (%d)",
|
||||
name, errno);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (x->ctltype[x->ctlmax - 1]) {
|
||||
switch (i) {
|
||||
case CTLTYPE_QUAD:
|
||||
xsnprintf(val.s, sizeof(val.s), "%" PRIu64, val.q);
|
||||
break;
|
||||
case CTLTYPE_INT:
|
||||
xsnprintf(val.s, sizeof(val.s), "%d", val.i);
|
||||
break;
|
||||
case CTLTYPE_STRING:
|
||||
break;
|
||||
default:
|
||||
xwarnx("unsupported sysctl type %d",
|
||||
x->ctltype[x->ctlmax - 1]);
|
||||
xwarnx("unsupported sysctl type %d", (int)i);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: paths.c,v 1.30 2004/03/16 05:25:12 atatat Exp $ */
|
||||
/* $NetBSD: paths.c,v 1.31 2004/07/05 11:50:07 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 Matt Thomas <matt@3am-software.com>
|
||||
@ -216,49 +216,6 @@ _rtld_add_paths(Search_Path **path_p, const char *pathstr)
|
||||
}
|
||||
}
|
||||
|
||||
struct list {
|
||||
const struct ctlname *ctl;
|
||||
int numentries;
|
||||
};
|
||||
|
||||
#ifdef CTL_MACHDEP_NAMES
|
||||
static const struct ctlname ctl_machdep[] = CTL_MACHDEP_NAMES;
|
||||
#endif
|
||||
static const struct ctlname ctl_toplvl[] = CTL_NAMES;
|
||||
|
||||
const struct list toplevel[] = {
|
||||
{ 0, 0 },
|
||||
{ ctl_toplvl, CTL_MAXID },
|
||||
{ 0, -1 },
|
||||
};
|
||||
|
||||
const struct list secondlevel[] = {
|
||||
{ 0, 0 }, /* CTL_UNSPEC */
|
||||
{ 0, KERN_MAXID }, /* CTL_KERN */
|
||||
{ 0, VM_MAXID }, /* CTL_VM */
|
||||
{ 0, VFS_MAXID }, /* CTL_VFS */
|
||||
{ 0, NET_MAXID }, /* CTL_NET */
|
||||
{ 0, CTL_DEBUG_MAXID }, /* CTL_DEBUG */
|
||||
{ 0, HW_MAXID }, /* CTL_HW */
|
||||
#ifdef CTL_MACHDEP_NAMES
|
||||
{ ctl_machdep, CPU_MAXID }, /* CTL_MACHDEP */
|
||||
#else
|
||||
{ 0, 0 }, /* CTL_MACHDEP */
|
||||
#endif
|
||||
{ 0, USER_MAXID }, /* CTL_USER_NAMES */
|
||||
{ 0, DDBCTL_MAXID }, /* CTL_DDB_NAMES */
|
||||
{ 0, 2 }, /* dummy name */
|
||||
{ 0, -1 },
|
||||
};
|
||||
|
||||
const struct list *lists[] = {
|
||||
toplevel,
|
||||
secondlevel,
|
||||
0
|
||||
};
|
||||
|
||||
#define CTL_MACHDEP_SIZE (sizeof(ctl_machdep) / sizeof(ctl_machdep[0]))
|
||||
|
||||
/*
|
||||
* Process library mappings of the form:
|
||||
* <library_name> <machdep_variable> <value,...:library_name,...> ...
|
||||
@ -268,7 +225,7 @@ _rtld_process_mapping(Library_Xform **lib_p, const char *bp, const char *ep)
|
||||
{
|
||||
Library_Xform *hwptr = NULL;
|
||||
const char *ptr, *key, *ekey, *lib, *elib, *l;
|
||||
int i, j, k;
|
||||
int i, j;
|
||||
|
||||
dbg((" processing mapping \"%.*s\"", (int)(ep - bp), bp));
|
||||
|
||||
@ -290,37 +247,7 @@ _rtld_process_mapping(Library_Xform **lib_p, const char *bp, const char *ep)
|
||||
|
||||
dbg((" sysctl \"%.*s\"", (int)(bp - ptr), ptr));
|
||||
|
||||
for (i = 0; (l = getstr(&ptr, bp, ".")) != NULL; i++, ptr++) {
|
||||
|
||||
if (lists[i] == NULL || i >= RTLD_MAX_CTL) {
|
||||
xwarnx("sysctl nesting too deep");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (j = 1; lists[i][j].numentries != -1; j++) {
|
||||
|
||||
if (lists[i][j].ctl == NULL)
|
||||
continue;
|
||||
|
||||
for (k = 1; k < lists[i][j].numentries; k++)
|
||||
if (matchstr(lists[i][j].ctl[k].ctl_name, l,
|
||||
ptr))
|
||||
break;
|
||||
|
||||
if (lists[i][j].numentries == -1) {
|
||||
xwarnx("unknown sysctl variable name `%.*s'",
|
||||
(int)(ptr - l), l);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hwptr->ctl[hwptr->ctlmax] = k;
|
||||
hwptr->ctltype[hwptr->ctlmax++] =
|
||||
lists[i][j].ctl[k].ctl_type;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < hwptr->ctlmax; i++)
|
||||
dbg((" sysctl %d, %d", hwptr->ctl[i], hwptr->ctltype[i]));
|
||||
hwptr->ctlname = exstrdup(ptr, bp);
|
||||
|
||||
for (i = 0; bp++, (ptr = getword(&bp, ep, WS)) != NULL;) {
|
||||
dbg((" ptr = %.*s", (int)(bp - ptr), ptr));
|
||||
@ -456,3 +383,71 @@ _rtld_process_hints(Search_Path **path_p, Library_Xform **lib_p,
|
||||
|
||||
(void)munmap(buf, sz);
|
||||
}
|
||||
|
||||
/* Basic name -> sysctl MIB translation */
|
||||
int
|
||||
_rtld_sysctl(const char *name, void *oldp, size_t *oldlen)
|
||||
{
|
||||
const char *node, *ep;
|
||||
struct sysctlnode query, *result, *newresult;
|
||||
int mib[CTL_MAXNAME], i, r;
|
||||
size_t res_size, n;
|
||||
u_int miblen = 0;
|
||||
|
||||
/* Start with 16 entries, will grow it up as needed. */
|
||||
res_size = 16 * sizeof(struct sysctlnode);
|
||||
result = (struct sysctlnode *)malloc(res_size);
|
||||
if (result == NULL)
|
||||
return (-1);
|
||||
|
||||
ep = name + strlen(name);
|
||||
do {
|
||||
while (*name == '/' || *name == '.')
|
||||
name++;
|
||||
if (name >= ep)
|
||||
break;
|
||||
|
||||
mib[miblen] = CTL_QUERY;
|
||||
memset(&query, 0, sizeof(query));
|
||||
query.sysctl_flags = SYSCTL_VERSION;
|
||||
|
||||
n = res_size;
|
||||
if (sysctl(mib, miblen+1, result, &n, &query,
|
||||
sizeof(query)) == -1) {
|
||||
if (errno != ENOMEM)
|
||||
goto bad;
|
||||
/* Grow up result */
|
||||
res_size = n;
|
||||
newresult = (struct sysctlnode *)realloc(result, res_size);
|
||||
if (newresult == NULL)
|
||||
goto bad;
|
||||
result = newresult;
|
||||
if (sysctl(mib, miblen+1, result, &n, &query,
|
||||
sizeof(query)) == -1)
|
||||
goto bad;
|
||||
}
|
||||
n /= sizeof(struct sysctlnode);
|
||||
|
||||
node = getstr(&name, ep, "./");
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
if (matchstr(result[i].sysctl_name, node, name)) {
|
||||
mib[miblen] = result[i].sysctl_num;
|
||||
miblen++;
|
||||
break;
|
||||
}
|
||||
} while (name < ep && miblen <= CTL_MAXNAME);
|
||||
|
||||
if (name < ep)
|
||||
goto bad;
|
||||
r = SYSCTL_TYPE(result[i].sysctl_flags);
|
||||
|
||||
free(result);
|
||||
if (sysctl(mib, miblen, oldp, oldlen, NULL, 0) == -1)
|
||||
return (-1);
|
||||
return r;
|
||||
|
||||
bad:
|
||||
free(result);
|
||||
return (-1);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtld.h,v 1.70 2003/08/12 09:18:49 skrll Exp $ */
|
||||
/* $NetBSD: rtld.h,v 1.71 2004/07/05 11:50:07 cube Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -97,9 +97,7 @@ typedef struct _rtld_search_path_t {
|
||||
typedef struct _rtld_library_xform_t {
|
||||
struct _rtld_library_xform_t *next;
|
||||
char *name;
|
||||
int ctl[RTLD_MAX_CTL];
|
||||
int ctltype[RTLD_MAX_CTL];
|
||||
int ctlmax;
|
||||
const char *ctlname;
|
||||
struct {
|
||||
char *value;
|
||||
char *library[RTLD_MAX_LIBRARY];
|
||||
@ -243,6 +241,7 @@ int _rtld_preload(const char *);
|
||||
/* path.c */
|
||||
void _rtld_add_paths(Search_Path **, const char *);
|
||||
void _rtld_process_hints(Search_Path **, Library_Xform **, const char *);
|
||||
int _rtld_sysctl(const char *, void *, size_t *);
|
||||
|
||||
/* reloc.c */
|
||||
int _rtld_do_copy_relocations(const Obj_Entry *);
|
||||
|
Loading…
Reference in New Issue
Block a user