mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-10-18 20:05:38 +08:00
Update to FreeBSD head 2016-08-23
Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd.
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <rtems/bsd/local/opt_ddb.h>
|
||||
#include <rtems/bsd/local/opt_kld.h>
|
||||
#include <rtems/bsd/local/opt_hwpmc_hooks.h>
|
||||
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
@@ -55,6 +56,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#ifdef DDB
|
||||
#include <ddb/ddb.h>
|
||||
#endif
|
||||
|
||||
#include <net/vnet.h>
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
@@ -68,10 +73,16 @@ __FBSDID("$FreeBSD$");
|
||||
#ifndef __rtems__
|
||||
#ifdef KLD_DEBUG
|
||||
int kld_debug = 0;
|
||||
SYSCTL_INT(_debug, OID_AUTO, kld_debug, CTLFLAG_RW,
|
||||
&kld_debug, 0, "Set various levels of KLD debug");
|
||||
SYSCTL_INT(_debug, OID_AUTO, kld_debug, CTLFLAG_RWTUN,
|
||||
&kld_debug, 0, "Set various levels of KLD debug");
|
||||
#endif
|
||||
|
||||
/* These variables are used by kernel debuggers to enumerate loaded files. */
|
||||
const int kld_off_address = offsetof(struct linker_file, address);
|
||||
const int kld_off_filename = offsetof(struct linker_file, filename);
|
||||
const int kld_off_pathname = offsetof(struct linker_file, pathname);
|
||||
const int kld_off_next = offsetof(struct linker_file, link.tqe_next);
|
||||
|
||||
/*
|
||||
* static char *linker_search_path(const char *name, struct mod_depend
|
||||
* *verinfo);
|
||||
@@ -143,18 +154,8 @@ static caddr_t linker_file_lookup_symbol_internal(linker_file_t file,
|
||||
const char* name, int deps);
|
||||
static int linker_load_module(const char *kldname,
|
||||
const char *modname, struct linker_file *parent,
|
||||
struct mod_depend *verinfo, struct linker_file **lfpp);
|
||||
static modlist_t modlist_lookup2(const char *name, struct mod_depend *verinfo);
|
||||
|
||||
static char *
|
||||
linker_strdup(const char *str)
|
||||
{
|
||||
char *result;
|
||||
|
||||
if ((result = malloc((strlen(str) + 1), M_LINKER, M_WAITOK)) != NULL)
|
||||
strcpy(result, str);
|
||||
return (result);
|
||||
}
|
||||
const struct mod_depend *verinfo, struct linker_file **lfpp);
|
||||
static modlist_t modlist_lookup2(const char *name, const struct mod_depend *verinfo);
|
||||
|
||||
static void
|
||||
linker_init(void *arg)
|
||||
@@ -306,10 +307,10 @@ linker_file_register_sysctls(linker_file_t lf)
|
||||
return;
|
||||
|
||||
sx_xunlock(&kld_sx);
|
||||
sysctl_lock();
|
||||
sysctl_wlock();
|
||||
for (oidp = start; oidp < stop; oidp++)
|
||||
sysctl_register_oid(*oidp);
|
||||
sysctl_unlock();
|
||||
sysctl_wunlock();
|
||||
sx_xlock(&kld_sx);
|
||||
}
|
||||
|
||||
@@ -318,7 +319,7 @@ linker_file_unregister_sysctls(linker_file_t lf)
|
||||
{
|
||||
struct sysctl_oid **start, **stop, **oidp;
|
||||
|
||||
KLD_DPF(FILE, ("linker_file_unregister_sysctls: registering SYSCTLs"
|
||||
KLD_DPF(FILE, ("linker_file_unregister_sysctls: unregistering SYSCTLs"
|
||||
" for %s\n", lf->filename));
|
||||
|
||||
sx_assert(&kld_sx, SA_XLOCKED);
|
||||
@@ -327,10 +328,10 @@ linker_file_unregister_sysctls(linker_file_t lf)
|
||||
return;
|
||||
|
||||
sx_xunlock(&kld_sx);
|
||||
sysctl_lock();
|
||||
sysctl_wlock();
|
||||
for (oidp = start; oidp < stop; oidp++)
|
||||
sysctl_unregister_oid(*oidp);
|
||||
sysctl_unlock();
|
||||
sysctl_wunlock();
|
||||
sx_xlock(&kld_sx);
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
@@ -598,11 +599,13 @@ linker_make_file(const char *pathname, linker_class_t lc)
|
||||
lf = (linker_file_t)kobj_create((kobj_class_t)lc, M_LINKER, M_WAITOK);
|
||||
if (lf == NULL)
|
||||
return (NULL);
|
||||
lf->ctors_addr = 0;
|
||||
lf->ctors_size = 0;
|
||||
lf->refs = 1;
|
||||
lf->userrefs = 0;
|
||||
lf->flags = 0;
|
||||
lf->filename = linker_strdup(filename);
|
||||
lf->pathname = linker_strdup(pathname);
|
||||
lf->filename = strdup(filename, M_LINKER);
|
||||
lf->pathname = strdup(pathname, M_LINKER);
|
||||
LINKER_GET_NEXT_FILE_ID(lf->id);
|
||||
lf->ndeps = 0;
|
||||
lf->deps = NULL;
|
||||
@@ -966,7 +969,7 @@ linker_debug_search_symbol_name(caddr_t value, char *buf, u_int buflen,
|
||||
*
|
||||
* Note that we do not obey list locking protocols here. We really don't need
|
||||
* DDB to hang because somebody's got the lock held. We'll take the chance
|
||||
* that the files list is inconsistant instead.
|
||||
* that the files list is inconsistent instead.
|
||||
*/
|
||||
#ifdef DDB
|
||||
int
|
||||
@@ -1009,9 +1012,9 @@ linker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
|
||||
{
|
||||
int error;
|
||||
|
||||
sx_xlock(&kld_sx);
|
||||
sx_slock(&kld_sx);
|
||||
error = linker_debug_search_symbol_name(value, buf, buflen, offset);
|
||||
sx_xunlock(&kld_sx);
|
||||
sx_sunlock(&kld_sx);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -1042,7 +1045,7 @@ kern_kldload(struct thread *td, const char *file, int *fileid)
|
||||
* (kldname.ko, or kldname.ver.ko) treat it as an interface
|
||||
* name.
|
||||
*/
|
||||
if (index(file, '/') || index(file, '.')) {
|
||||
if (strchr(file, '/') || strchr(file, '.')) {
|
||||
kldname = file;
|
||||
modname = NULL;
|
||||
} else {
|
||||
@@ -1273,6 +1276,23 @@ kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef DDB
|
||||
DB_COMMAND(kldstat, db_kldstat)
|
||||
{
|
||||
linker_file_t lf;
|
||||
|
||||
#define POINTER_WIDTH ((int)(sizeof(void *) * 2 + 2))
|
||||
db_printf("Id Refs Address%*c Size Name\n", POINTER_WIDTH - 7, ' ');
|
||||
#undef POINTER_WIDTH
|
||||
TAILQ_FOREACH(lf, &linker_files, link) {
|
||||
if (db_pager_quit)
|
||||
return;
|
||||
db_printf("%2d %4d %p %-8zx %s\n", lf->id, lf->refs,
|
||||
lf->address, lf->size, lf->filename);
|
||||
}
|
||||
}
|
||||
#endif /* DDB */
|
||||
|
||||
int
|
||||
sys_kldfirstmod(struct thread *td, struct kldfirstmod_args *uap)
|
||||
{
|
||||
@@ -1376,7 +1396,7 @@ modlist_lookup(const char *name, int ver)
|
||||
}
|
||||
|
||||
static modlist_t
|
||||
modlist_lookup2(const char *name, struct mod_depend *verinfo)
|
||||
modlist_lookup2(const char *name, const struct mod_depend *verinfo)
|
||||
{
|
||||
modlist_t mod, bestmod;
|
||||
int ver;
|
||||
@@ -1426,7 +1446,7 @@ linker_addmodules(linker_file_t lf, struct mod_metadata **start,
|
||||
if (mp->md_type != MDT_VERSION)
|
||||
continue;
|
||||
modname = mp->md_cval;
|
||||
ver = ((struct mod_version *)mp->md_data)->mv_version;
|
||||
ver = ((const struct mod_version *)mp->md_data)->mv_version;
|
||||
if (modlist_lookup(modname, ver) != NULL) {
|
||||
printf("module %s already present!\n", modname);
|
||||
/* XXX what can we do? this is a build error. :-( */
|
||||
@@ -1449,7 +1469,7 @@ linker_preload(void *arg)
|
||||
linker_file_list_t depended_files;
|
||||
struct mod_metadata *mp, *nmp;
|
||||
struct mod_metadata **start, **stop, **mdp, **nmdp;
|
||||
struct mod_depend *verinfo;
|
||||
const struct mod_depend *verinfo;
|
||||
int nver;
|
||||
int resolves;
|
||||
modlist_t mod;
|
||||
@@ -1547,7 +1567,7 @@ restart:
|
||||
if (mp->md_type != MDT_VERSION)
|
||||
continue;
|
||||
modname = mp->md_cval;
|
||||
nver = ((struct mod_version *)
|
||||
nver = ((const struct mod_version *)
|
||||
mp->md_data)->mv_version;
|
||||
if (modlist_lookup(modname,
|
||||
nver) != NULL) {
|
||||
@@ -1667,7 +1687,7 @@ SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0);
|
||||
static char linker_hintfile[] = "linker.hints";
|
||||
static char linker_path[MAXPATHLEN] = "/boot/kernel;/boot/modules";
|
||||
|
||||
SYSCTL_STRING(_kern, OID_AUTO, module_path, CTLFLAG_RW, linker_path,
|
||||
SYSCTL_STRING(_kern, OID_AUTO, module_path, CTLFLAG_RWTUN, linker_path,
|
||||
sizeof(linker_path), "module load search path");
|
||||
|
||||
TUNABLE_STR("module_path", linker_path, sizeof(linker_path));
|
||||
@@ -1690,7 +1710,7 @@ linker_lookup_file(const char *path, int pathlen, const char *name,
|
||||
struct nameidata nd;
|
||||
struct thread *td = curthread; /* XXX */
|
||||
char *result, **cpp, *sep;
|
||||
int error, len, extlen, reclen, flags, vfslocked;
|
||||
int error, len, extlen, reclen, flags;
|
||||
enum vtype type;
|
||||
|
||||
extlen = 0;
|
||||
@@ -1711,18 +1731,16 @@ linker_lookup_file(const char *path, int pathlen, const char *name,
|
||||
* Attempt to open the file, and return the path if
|
||||
* we succeed and it's a regular file.
|
||||
*/
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, result, td);
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, result, td);
|
||||
flags = FREAD;
|
||||
error = vn_open(&nd, &flags, 0, NULL);
|
||||
if (error == 0) {
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
type = nd.ni_vp->v_type;
|
||||
if (vap)
|
||||
VOP_GETATTR(nd.ni_vp, vap, td->td_ucred);
|
||||
VOP_UNLOCK(nd.ni_vp, 0);
|
||||
vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
if (type == VREG)
|
||||
return (result);
|
||||
}
|
||||
@@ -1732,7 +1750,7 @@ linker_lookup_file(const char *path, int pathlen, const char *name,
|
||||
}
|
||||
|
||||
#define INT_ALIGN(base, ptr) ptr = \
|
||||
(base) + (((ptr) - (base) + sizeof(int) - 1) & ~(sizeof(int) - 1))
|
||||
(base) + roundup2((ptr) - (base), sizeof(int))
|
||||
|
||||
/*
|
||||
* Lookup KLD which contains requested module in the "linker.hints" file. If
|
||||
@@ -1741,7 +1759,7 @@ linker_lookup_file(const char *path, int pathlen, const char *name,
|
||||
*/
|
||||
static char *
|
||||
linker_hints_lookup(const char *path, int pathlen, const char *modname,
|
||||
int modnamelen, struct mod_depend *verinfo)
|
||||
int modnamelen, const struct mod_depend *verinfo)
|
||||
{
|
||||
struct thread *td = curthread; /* XXX */
|
||||
struct ucred *cred = td ? td->td_ucred : NULL;
|
||||
@@ -1751,7 +1769,6 @@ linker_hints_lookup(const char *path, int pathlen, const char *modname,
|
||||
u_char *cp, *recptr, *bufend, *result, *best, *pathbuf, *sep;
|
||||
int error, ival, bestver, *intp, found, flags, clen, blen;
|
||||
ssize_t reclen;
|
||||
int vfslocked = 0;
|
||||
|
||||
result = NULL;
|
||||
bestver = found = 0;
|
||||
@@ -1763,12 +1780,11 @@ linker_hints_lookup(const char *path, int pathlen, const char *modname,
|
||||
snprintf(pathbuf, reclen, "%.*s%s%s", pathlen, path, sep,
|
||||
linker_hintfile);
|
||||
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, pathbuf, td);
|
||||
NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, pathbuf, td);
|
||||
flags = FREAD;
|
||||
error = vn_open(&nd, &flags, 0, NULL);
|
||||
if (error)
|
||||
goto bad;
|
||||
vfslocked = NDHASGIANT(&nd);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
if (nd.ni_vp->v_type != VREG)
|
||||
goto bad;
|
||||
@@ -1779,20 +1795,17 @@ linker_hints_lookup(const char *path, int pathlen, const char *modname,
|
||||
/*
|
||||
* XXX: we need to limit this number to some reasonable value
|
||||
*/
|
||||
if (vattr.va_size > 100 * 1024) {
|
||||
if (vattr.va_size > LINKER_HINTS_MAX) {
|
||||
printf("hints file too large %ld\n", (long)vattr.va_size);
|
||||
goto bad;
|
||||
}
|
||||
hints = malloc(vattr.va_size, M_TEMP, M_WAITOK);
|
||||
if (hints == NULL)
|
||||
goto bad;
|
||||
error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)hints, vattr.va_size, 0,
|
||||
UIO_SYSSPACE, IO_NODELOCKED, cred, NOCRED, &reclen, td);
|
||||
if (error)
|
||||
goto bad;
|
||||
VOP_UNLOCK(nd.ni_vp, 0);
|
||||
vn_close(nd.ni_vp, FREAD, cred, td);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
nd.ni_vp = NULL;
|
||||
if (reclen != 0) {
|
||||
printf("can't read %zd\n", reclen);
|
||||
@@ -1861,7 +1874,6 @@ bad:
|
||||
if (nd.ni_vp != NULL) {
|
||||
VOP_UNLOCK(nd.ni_vp, 0);
|
||||
vn_close(nd.ni_vp, FREAD, cred, td);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
}
|
||||
/*
|
||||
* If nothing found or hints is absent - fallback to the old
|
||||
@@ -1878,7 +1890,7 @@ bad:
|
||||
*/
|
||||
static char *
|
||||
linker_search_module(const char *modname, int modnamelen,
|
||||
struct mod_depend *verinfo)
|
||||
const struct mod_depend *verinfo)
|
||||
{
|
||||
char *cp, *ep, *result;
|
||||
|
||||
@@ -1908,8 +1920,8 @@ linker_search_kld(const char *name)
|
||||
int len;
|
||||
|
||||
/* qualified at all? */
|
||||
if (index(name, '/'))
|
||||
return (linker_strdup(name));
|
||||
if (strchr(name, '/'))
|
||||
return (strdup(name, M_LINKER));
|
||||
|
||||
/* traverse the linker path */
|
||||
len = strlen(name);
|
||||
@@ -1929,7 +1941,7 @@ linker_basename(const char *path)
|
||||
{
|
||||
const char *filename;
|
||||
|
||||
filename = rindex(path, '/');
|
||||
filename = strrchr(path, '/');
|
||||
if (filename == NULL)
|
||||
return path;
|
||||
if (filename[1])
|
||||
@@ -1982,7 +1994,7 @@ linker_hwpmc_list_objects(void)
|
||||
*/
|
||||
static int
|
||||
linker_load_module(const char *kldname, const char *modname,
|
||||
struct linker_file *parent, struct mod_depend *verinfo,
|
||||
struct linker_file *parent, const struct mod_depend *verinfo,
|
||||
struct linker_file **lfpp)
|
||||
{
|
||||
linker_file_t lfdep;
|
||||
@@ -2002,7 +2014,7 @@ linker_load_module(const char *kldname, const char *modname,
|
||||
if (modlist_lookup2(modname, verinfo) != NULL)
|
||||
return (EEXIST);
|
||||
if (kldname != NULL)
|
||||
pathname = linker_strdup(kldname);
|
||||
pathname = strdup(kldname, M_LINKER);
|
||||
else if (rootvnode == NULL)
|
||||
pathname = NULL;
|
||||
else
|
||||
@@ -2056,13 +2068,13 @@ linker_load_dependencies(linker_file_t lf)
|
||||
linker_file_t lfdep;
|
||||
struct mod_metadata **start, **stop, **mdp, **nmdp;
|
||||
struct mod_metadata *mp, *nmp;
|
||||
struct mod_depend *verinfo;
|
||||
const struct mod_depend *verinfo;
|
||||
modlist_t mod;
|
||||
const char *modname, *nmodname;
|
||||
int ver, error = 0, count;
|
||||
|
||||
/*
|
||||
* All files are dependant on /kernel.
|
||||
* All files are dependent on /kernel.
|
||||
*/
|
||||
sx_assert(&kld_sx, SA_XLOCKED);
|
||||
if (linker_kernel_file) {
|
||||
@@ -2079,7 +2091,7 @@ linker_load_dependencies(linker_file_t lf)
|
||||
if (mp->md_type != MDT_VERSION)
|
||||
continue;
|
||||
modname = mp->md_cval;
|
||||
ver = ((struct mod_version *)mp->md_data)->mv_version;
|
||||
ver = ((const struct mod_version *)mp->md_data)->mv_version;
|
||||
mod = modlist_lookup(modname, ver);
|
||||
if (mod != NULL) {
|
||||
printf("interface %s.%d already present in the KLD"
|
||||
|
Reference in New Issue
Block a user